package cn.stylefeng.guns.modular.hx.order.service.impl;

import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.sql.DataSource;

import cn.stylefeng.guns.core.util.DateUtil2;
import cn.stylefeng.guns.modular.basic.entity.BasicGoods;
import cn.stylefeng.guns.modular.basic.model.result.BasicCustomerResult;
import cn.stylefeng.guns.modular.basic.model.result.BasicPositionResult;
import cn.stylefeng.guns.modular.hx.order.model.vo.*;
import cn.stylefeng.guns.modular.hx.order.utils.JdbcUtls;
import cn.stylefeng.guns.modular.hx.storage.entity.HxStorageStock;
import cn.stylefeng.guns.modular.kh.entity.KhWare;
import cn.stylefeng.guns.modular.kh.service.KhWareService;
import cn.stylefeng.guns.modular.order.model.params.OrderClientVolSumParam;
import cn.stylefeng.guns.sys.modular.system.service.DictService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.modular.basic.entity.BasicCustomer;
import cn.stylefeng.guns.modular.basic.entity.BasicPutgoods;
import cn.stylefeng.guns.modular.basic.entity.BasicWarehouse;
import cn.stylefeng.guns.modular.basic.model.params.BasicAddressParam;
import cn.stylefeng.guns.modular.basic.model.params.BasicPutgoodsParam;
import cn.stylefeng.guns.modular.basic.model.result.BasicAddressResult;
import cn.stylefeng.guns.modular.basic.model.result.BasicPutgoodsResult;
import cn.stylefeng.guns.modular.basic.service.BasicAddressService;
import cn.stylefeng.guns.modular.basic.service.BasicCustomerService;
import cn.stylefeng.guns.modular.basic.service.BasicPutgoodsService;
import cn.stylefeng.guns.modular.basic.service.BasicTrayService;
import cn.stylefeng.guns.modular.basic.service.BasicWarehouseService;
import cn.stylefeng.guns.modular.hx.basic.entity.HxBasicGoods;
import cn.stylefeng.guns.modular.hx.basic.model.params.HxBasicGoodsParam;
import cn.stylefeng.guns.modular.hx.basic.model.params.HxBasicPositionGoodsParam;
import cn.stylefeng.guns.modular.hx.basic.model.result.HxBasicGoodsResult;
import cn.stylefeng.guns.modular.hx.basic.model.result.HxBasicPositionGoodsResult;
import cn.stylefeng.guns.modular.hx.basic.service.HxBasicGoodsService;
import cn.stylefeng.guns.modular.hx.basic.service.HxBasicPositionGoodsService;
import cn.stylefeng.guns.modular.hx.order.entity.HxOrderOut;
import cn.stylefeng.guns.modular.hx.order.entity.HxOrderOutExcelItem;
import cn.stylefeng.guns.modular.hx.order.mapper.HxOrderOutMapper;
import cn.stylefeng.guns.modular.hx.order.model.params.HxOrderOutDetailedParam;
import cn.stylefeng.guns.modular.hx.order.model.params.HxOrderOutParam;
import cn.stylefeng.guns.modular.hx.order.model.result.HxOrderOutDetailedResult;
import cn.stylefeng.guns.modular.hx.order.model.result.HxOrderOutResult;
import cn.stylefeng.guns.modular.hx.order.service.HxOrderOutDetailedService;
import cn.stylefeng.guns.modular.hx.order.service.HxOrderOutService;
import cn.stylefeng.guns.modular.hx.storage.entity.HxStorageOut;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageOffShelfParam;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageOutDetailedParam;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageOutParam;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageStockParam;
import cn.stylefeng.guns.modular.hx.storage.model.result.HxStorageOffShelfResult;
import cn.stylefeng.guns.modular.hx.storage.model.result.HxStorageOutDetailedResult;
import cn.stylefeng.guns.modular.hx.storage.model.result.HxStorageStockResult;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageOffShelfService;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageOutDetailedService;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageOutService;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageStockService;
import cn.stylefeng.guns.modular.order.model.params.DealWithParam;
import cn.stylefeng.guns.sys.modular.system.entity.Dept;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.service.DeptService;
import cn.stylefeng.guns.sys.modular.system.service.UserService;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;

/**
 * <p>
 * 出库订单表 服务实现类
 * </p>
 *
 * @author zhucx
 * @since 2023-08-30
 */
@Service
public class HxOrderOutServiceImpl extends ServiceImpl<HxOrderOutMapper, HxOrderOut> implements HxOrderOutService {

    @Autowired
    private DataSource dataSource;

    @Override
    public void add(HxOrderOutParam param) {
        HxOrderOut entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(HxOrderOutParam param) {
        this.removeById(getKey(param));
    }

    @Override
    public void update(HxOrderOutParam param) {
        HxOrderOut oldEntity = getOldEntity(param);
        HxOrderOut newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public HxOrderOutResult findBySpec(HxOrderOutParam param) {
        return this.baseMapper.findBySpec(param);
    }

    @Override
    public List<HxOrderOutResult> findListBySpec(HxOrderOutParam param) {
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(HxOrderOutParam param, String condition, Long operateId) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param, condition, operateId);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public LayuiPageInfo findqueryPageBySpec(HxOrderOutParam param, String condition, Long operateId) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.findqueryPageBySpec(pageContext, param, condition, operateId);
        return LayuiPageFactory.createPageInfo(page);
    }

    private Serializable getKey(HxOrderOutParam param) {
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private HxOrderOut getOldEntity(HxOrderOutParam param) {
        return this.getById(getKey(param));
    }

    private HxOrderOut getEntity(HxOrderOutParam param) {
        HxOrderOut entity = new HxOrderOut();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    @Override
    public HxOrderOut findByThelastone() {
        return this.baseMapper.findByThelastone();
    }

    @Override
    public boolean checkCustomerOrder(String orderOutNumber) {
        return this.baseMapper.checkCustomerOrder(orderOutNumber) == null ? false : true;
    }

    private static String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }
        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            if (DateUtil.isCellDateFormatted(cell)) {
                return HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString();
            } else {
                return new BigDecimal(Double.toString(cell.getNumericCellValue())).toString();
            }
        } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
            return StringUtils.trimToEmpty(cell.getStringCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
            return StringUtils.trimToEmpty(cell.getCellFormula());
        } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
            return "";
        } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
            return "ERROR";
        } else {
            return cell.toString().trim();
        }
    }

    @Resource
    private BasicCustomerService basicCustomerService;

    @Resource
    private BasicWarehouseService basicWarehouseService;

    @Resource
    private UserService userService;

    @Resource
    private HxBasicGoodsService hxBasicGoodsService;

    @Resource
    private BasicPutgoodsService basicPutgoodsService;

    @Resource
    private HxOrderOutDetailedService hxOrderOutDetailedService;

    @Resource
    private DeptService deptService;

    /**
     * 获取所属项目单号前缀
     *
     * @param user
     * @return
     */
    public String getOperateIdOrderPrefix(User user) {
        if (user.getOperateId() != null) {
            Dept dept = new Dept();
            dept.setOperateId(user.getOperateId());
            Dept resdept = deptService.findBySpec(dept);
            if (resdept != null) {
                if (ToolUtil.isNotEmpty(resdept.getOrderPrefix())) {
                    return resdept.getOrderPrefix();
                } else {
                    return user.getAccount().substring(0, 3);
                }
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 600)
    public ResponseData getExceldata(MultipartFile file, HxOrderOutParam hxOrderOutParam, ResponseData data) throws Exception {
        String fileName = file.getOriginalFilename();
        List<HxOrderOutExcelItem> list = new ArrayList<HxOrderOutExcelItem>();

        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            data.setMessage("上传文件格式不正确");
            data.setSuccess(false);
        }
        boolean isExcel2003 = true;
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            isExcel2003 = false;
        }
        InputStream is = file.getInputStream();
        Workbook wb = null;
        if (isExcel2003) {
            wb = new HSSFWorkbook(is);
        } else {
            wb = new XSSFWorkbook(is);
        }
        Sheet sheet = wb.getSheetAt(0);

        for (int r = 1; r <= sheet.getLastRowNum() + 1; r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            HxOrderOutExcelItem excelItem = new HxOrderOutExcelItem();

            String peisongTime = getCellValue(row.getCell(0));
            if (ToolUtil.isNotEmpty(peisongTime)) {
                excelItem.setPeisongTime(peisongTime);
            }

            String orderOutNumber = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(1));
            if (ToolUtil.isNotEmpty(orderOutNumber)) {
                excelItem.setOrderOutNumber(orderOutNumber);
            }

            String getUnit = getCellValue(row.getCell(2));
            if (ToolUtil.isNotEmpty(getUnit)) {
                excelItem.setGetUnit(getUnit);
            }

            String unitNumber = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(3));
            if (ToolUtil.isNotEmpty(unitNumber)) {
                excelItem.setUnitNumber(unitNumber);
            }

            String address = getCellValue(row.getCell(4));
            if (ToolUtil.isNotEmpty(address)) {
                excelItem.setAddress(address);
            }

            String contacts = getCellValue(row.getCell(5));
            if (ToolUtil.isNotEmpty(contacts)) {
                excelItem.setContacts(contacts);
            }

            String tel = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(6));
            if (ToolUtil.isNotEmpty(tel)) {
                excelItem.setTel(tel);
            }

            String goodsNumber = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(7));
            if (ToolUtil.isNotEmpty(goodsNumber)) {
                excelItem.setGoodsNumber(goodsNumber);
            }

            String goodsName = getCellValue(row.getCell(8));
            if (ToolUtil.isNotEmpty(goodsName)) {
                excelItem.setGoodsName(goodsName);
            }

            String detailedDate = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(9));
            if (ToolUtil.isNotEmpty(detailedDate)) {
                excelItem.setDetailedDate(detailedDate);
            }

            String psNum = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(10));
            if (ToolUtil.isNotEmpty(psNum)) {
                excelItem.setPsNum(psNum);
            }

            String associationOrder = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(11));
            if (ToolUtil.isNotEmpty(associationOrder)) {
                excelItem.setAssociationOrder(associationOrder);
            }

            String associationOrderType = getCellValue(row.getCell(12));
            if (ToolUtil.isNotEmpty(associationOrderType)) {
                excelItem.setAssociationOrderType(associationOrderType);
            }

            String notes = getCellValue(row.getCell(13));
            if (ToolUtil.isNotEmpty(notes)) {
                excelItem.setNotes(notes);
            }
            list.add(excelItem);
        }
        BasicPutgoods fh = basicPutgoodsService.getById(hxOrderOutParam.getSetUnitId());
        BasicAddressParam basicAddressParam = new BasicAddressParam();
        basicAddressParam.setPutgoodsId(Long.parseLong(fh.getId().toString()));
        BasicAddressResult addressResult = basicAddressService.findBySpec(basicAddressParam);
        if (addressResult == null) {
            return ResponseData.error("装货地址不存在！请维护");
        }
        List<HxOrderOutParam> olist = new ArrayList<HxOrderOutParam>();//批量保存的 出库订单list
        List<HxOrderOutDetailedParam> detailedList = new ArrayList<HxOrderOutDetailedParam>();//批量保存的 订单商品明细list
        BasicCustomer basicCustomer = basicCustomerService.getById(hxOrderOutParam.getCustomerId());//客户信息
        BasicWarehouse basicWarehouse = basicWarehouseService.getById(hxOrderOutParam.getSetWarehouseId());//仓库信息

        User user = userService.getcurrentUser();
        Long deptId = user.getDeptId();
        Long deliverId = user.getDeliverId();
        String trayCode = getOperateIdOrderPrefix(user);
        HxOrderOut hxOrderOut = this.findByThelastone();
        int putNumber = 1;
        if (hxOrderOut != null) {
            putNumber = hxOrderOut.getId() + 1;
        }
        DealWithParam dealWithParam = new DealWithParam();
        dealWithParam.setNewCustomersflag(false);
		Map<String, HxBasicGoodsResult> goodsMap = new HashMap<>();
        HxBasicGoodsParam hxgoodsp = new HxBasicGoodsParam();
		hxgoodsp.setGoodsCustomerId(basicCustomer.getId());
		List<HxBasicGoodsResult> hxg = hxBasicGoodsService.findListBySpec(hxgoodsp);
		for (HxBasicGoodsResult gr : hxg) {
			goodsMap.put(gr.getGoodsNumber(), gr);
		}
        for (HxOrderOutExcelItem excelItem : list) {
            if (ToolUtil.isEmpty(excelItem.getGetUnit())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中收货客户不得为空!");
                return data;
            }
            if (ToolUtil.isEmpty(excelItem.getGoodsNumber())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中商品编号不得为空!");
                return data;
            }
            if (ToolUtil.isEmpty(excelItem.getPsNum())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中数量不得为空!");
                return data;
            }
            //通过 导入的订单号 查询是否存在
            HxOrderOutParam opp = new HxOrderOutParam();
            boolean whether2 = false;
            if (ToolUtil.isEmpty(excelItem.getOrderOutNumber())) {
                whether2 = true;
                boolean flags = false;
                for (HxOrderOutParam opp2 : olist) {
                    if (opp2.getGetUnit().equals(excelItem.getGetUnit())) {
                        flags = true;
                        excelItem.setOrderOutNumber(opp2.getOrderOutNumber());
                    }
                }
                if (!flags) {
                    excelItem.setOrderOutNumber(trayCode + "CK" + cn.stylefeng.guns.core.util.DateUtil.getDatesBch() + (putNumber));
                }
            }
            opp.setOrderOutNumber(excelItem.getOrderOutNumber());//订单号
            HxOrderOutResult hxOrderOutResult = this.findBySpec(opp);//状态不等于 作废
            //如果不存在
            if (hxOrderOutResult == null) {
                //新增出库订单
                opp.setCustomerId(hxOrderOutParam.getCustomerId());//客户id
                opp.setCustomerName(basicCustomer.getCustomerName());//客户名称
                opp.setOrderState("待提交");//订单状态
                opp.setPeisongTime(excelItem.getPeisongTime());
                opp.setOrderType(hxOrderOutParam.getOrderType());
                opp.setSetUnit(fh.getPutgoodsName());//装货单位
                opp.setSetUnitId(Long.parseLong(fh.getId().toString()));//装货单位id
                opp.setSetLocation(addressResult.getAddress());//装货地址
                opp.setSetLocationId(Long.parseLong(addressResult.getId().toString()));//装货地址id
                opp.setSetPeople(addressResult.getContacts());//联系人
                opp.setSetTel(addressResult.getTel());//联系电话
                opp.setSetWarehouseId(hxOrderOutParam.getSetWarehouseId());//仓库id
                opp.setSetWarehouse(basicWarehouse.getWarehouseName());//仓库名称
                toDealWith(opp, basicCustomer, excelItem, dealWithParam,user);//处理单位和地址
                opp.setCreateUserName(user.getName());//制单人名称
                opp.setCreateTime(new Date());
                opp.setNotes(excelItem.getNotes());
                opp.setAssociationOrder(excelItem.getAssociationOrder());
                opp.setAssociationOrderType(excelItem.getAssociationOrder());
                opp.setDeliverId(deliverId);//交付id
                opp.setDeptId(deptId);//部门id
                boolean whether = false;//判断单号  是否重复
                for (HxOrderOutParam opp2 : olist) {
                    if (opp2.getOrderOutNumber().equals(opp.getOrderOutNumber())) {
                        whether = true;
                        hxOrderOutResult = new HxOrderOutResult();
                        ToolUtil.copyProperties(opp2, hxOrderOutResult);
                    }
                }
                if (!whether) {
                    olist.add(opp);
                    if (whether2) {
                        putNumber++;
                    }
                    hxOrderOutResult = new HxOrderOutResult();
                    ToolUtil.copyProperties(opp, hxOrderOutResult);
                }
                opp = new HxOrderOutParam();
            } else {
                //如果 导入的客户单号 已存在
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中订单号:" + excelItem.getOrderOutNumber() + "已存在!");
                return data;
            }

			HxBasicGoodsResult hxBasicGoodsResult = goodsMap.get(excelItem.getGoodsNumber());
            if (hxBasicGoodsResult == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中商品" + excelItem.getGoodsNumber() + "系统不存在!请及时同步");
                return data;
            }

            HxOrderOutDetailedParam hxd = new HxOrderOutDetailedParam();
            BigDecimal psNum = new BigDecimal(excelItem.getPsNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);
            BigDecimal goodsVolume = new BigDecimal(hxBasicGoodsResult.getGoodsVolume());
            BigDecimal goodsWeight = new BigDecimal(hxBasicGoodsResult.getGoodsWeight());
            BigDecimal goodsPrice = new BigDecimal("0");

            hxd.setUnit(hxBasicGoodsResult.getPsUnit());
            hxd.setRate(hxBasicGoodsResult.getPsRate());
            BigDecimal psRate = new BigDecimal(hxBasicGoodsResult.getPsRate());
            BigDecimal jibenNum = psRate.multiply(psNum).setScale(3, BigDecimal.ROUND_HALF_DOWN);
            BigDecimal cgRate = new BigDecimal(hxBasicGoodsResult.getCgRate());
            if (psRate.compareTo(cgRate) == -1) {
                //如果配送换算率 小于 采购换算率：  配送体积  =  采购体积/（采购换算率/配送换算率）
                BigDecimal div = cgRate.divide(psRate, 3, BigDecimal.ROUND_HALF_DOWN);
                BigDecimal divv_v = goodsVolume.divide(div, 4, BigDecimal.ROUND_HALF_DOWN);
                goodsVolume = divv_v;
                BigDecimal divv_w = goodsWeight.divide(div, 3, BigDecimal.ROUND_HALF_DOWN);
                goodsWeight = divv_w;
            }
            if (psRate.compareTo(cgRate) == 1) {
                //如果配送换算率 大于 采购换算率：  配送体积  =  采购体积*（配送换算率/采购换算率）
                BigDecimal div = psRate.divide(cgRate, 3, BigDecimal.ROUND_HALF_DOWN);
                BigDecimal divv_v = goodsVolume.multiply(div).setScale(4, BigDecimal.ROUND_HALF_DOWN);
                goodsVolume = divv_v;
                BigDecimal divv_w = goodsWeight.multiply(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                goodsWeight = divv_w;
            }
            BigDecimal goodsChargingPs = new BigDecimal(hxBasicGoodsResult.getGoodsChargingPs());
            goodsPrice = psRate.multiply(goodsChargingPs).setScale(3, BigDecimal.ROUND_HALF_DOWN);

            //创建订单明细
            hxd.setOrderOutNumber(hxOrderOutResult.getOrderOutNumber());
            hxd.setGoodsId(Long.parseLong(hxBasicGoodsResult.getId().toString()));
            hxd.setGoodsName(hxBasicGoodsResult.getGoodsName());
            hxd.setGoodsNumber(hxBasicGoodsResult.getGoodsNumber());
            hxd.setGoodsPcode69(hxBasicGoodsResult.getGoodsPcode69());
            hxd.setGoodsXcode69(hxBasicGoodsResult.getGoodsXcode69());
            hxd.setGoodsHcode69(hxBasicGoodsResult.getGoodsHcode69());
            hxd.setGoodsSpecs(hxBasicGoodsResult.getGoodsSpecs());
            hxd.setDismantlingParts(hxBasicGoodsResult.getDismantlingParts());
            
            hxd.setJibenNum(jibenNum+"");
            hxd.setJibenUnit(hxBasicGoodsResult.getJibenUnit());

            hxd.setPsNum(psNum.toString());

            hxd.setGoodsWeight(goodsWeight.toString());
            hxd.setOutWeight(psNum.multiply(goodsWeight).setScale(3, BigDecimal.ROUND_HALF_DOWN).toString());
            hxd.setGoodsVolume(goodsVolume.toString());
            hxd.setOutVolume(psNum.multiply(goodsVolume).setScale(4, BigDecimal.ROUND_HALF_DOWN).toString());
            hxd.setGoodsPrice(goodsPrice.toString());
            hxd.setOutMoney(psNum.multiply(goodsPrice).setScale(3, BigDecimal.ROUND_HALF_DOWN).toString());
            hxd.setDetailedDate(excelItem.getDetailedDate());
            hxd.setNotes(excelItem.getNotes());

            detailedList.add(hxd);
            hxd = new HxOrderOutDetailedParam();
        }
        if (detailedList.size() > 0) {
            this.saveBatchList(olist);
            hxOrderOutDetailedService.saveBatchList(detailedList);
        }
        data.setSuccess(true);
        if (dealWithParam.isNewCustomersflag()) {
            data.setCode(450);
            data.setMessage(dealWithParam.getNewCustomers().replaceAll("null", ""));
        }
        return data;
    }


    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 600)
    public ResponseData getDuoDianExceldata(MultipartFile file, HxOrderOutParam hxOrderOutParam, ResponseData data) throws Exception {
        String fileName = file.getOriginalFilename();
        List<HxOrderOutExcelItem> list = new ArrayList<HxOrderOutExcelItem>();

        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            data.setMessage("上传文件格式不正确");
            data.setSuccess(false);
        }
        boolean isExcel2003 = true;
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            isExcel2003 = false;
        }
        InputStream is = file.getInputStream();
        Workbook wb = null;
        if (isExcel2003) {
            wb = new HSSFWorkbook(is);
        } else {
            wb = new XSSFWorkbook(is);
        }
        Sheet sheet = wb.getSheetAt(0);

        for (int r = 1; r <= sheet.getLastRowNum() + 1; r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            HxOrderOutExcelItem excelItem = new HxOrderOutExcelItem();

            String peisongTime = getCellValue(row.getCell(46));
            if (ToolUtil.isNotEmpty(peisongTime)) {
                excelItem.setPeisongTime(peisongTime);
            }

            String orderOutNumber = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(42));
            if (ToolUtil.isNotEmpty(orderOutNumber)) {
                excelItem.setOrderOutNumber(orderOutNumber);
            }

            String getUnit = getCellValue(row.getCell(32));
            if (ToolUtil.isNotEmpty(getUnit)) {
                excelItem.setGetUnit(getUnit);
            }

            String unitNumber = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(31));
            if (ToolUtil.isNotEmpty(unitNumber)) {
                excelItem.setUnitNumber(unitNumber);
            }

            String address = getCellValue(row.getCell(50));
            if (ToolUtil.isNotEmpty(address)) {
                excelItem.setAddress(address);
            }

            String goodsNumber = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(9));
            if (ToolUtil.isNotEmpty(goodsNumber)) {
                excelItem.setGoodsNumber(goodsNumber);
            }

            String goodsName = getCellValue(row.getCell(10));
            if (ToolUtil.isNotEmpty(goodsName)) {
                excelItem.setGoodsName(goodsName);
            }

//            String detailedDate = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(9));
//            if (ToolUtil.isNotEmpty(detailedDate)) {
//                excelItem.setDetailedDate(detailedDate);
//            }

            String psNum = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(11));
            if (ToolUtil.isNotEmpty(psNum)) {
                excelItem.setPsNum(psNum);
            }

            String psUnit = cn.stylefeng.guns.core.util.DateUtil.getCellValueByCell(row.getCell(13));
            if (ToolUtil.isNotEmpty(psUnit)) {
                excelItem.setPsUnit(psUnit);
            }


//            String notes = getCellValue(row.getCell(13));
//            if (ToolUtil.isNotEmpty(notes)) {
//                excelItem.setNotes(notes);
//            }
            list.add(excelItem);
        }
        BasicPutgoods fh = basicPutgoodsService.getById(hxOrderOutParam.getSetUnitId());
        BasicAddressParam basicAddressParam = new BasicAddressParam();
        basicAddressParam.setPutgoodsId(Long.parseLong(fh.getId().toString()));
        BasicAddressResult addressResult = basicAddressService.findBySpec(basicAddressParam);
        if (addressResult == null) {
            return ResponseData.error("装货地址不存在！请维护");
        }
        List<HxOrderOutParam> olist = new ArrayList<HxOrderOutParam>();//批量保存的 出库订单list
        List<HxOrderOutDetailedParam> detailedList = new ArrayList<HxOrderOutDetailedParam>();//批量保存的 订单商品明细list
        BasicCustomer basicCustomer = basicCustomerService.getById(hxOrderOutParam.getCustomerId());//客户信息
        BasicWarehouse basicWarehouse = basicWarehouseService.getById(hxOrderOutParam.getSetWarehouseId());//仓库信息

        User user = userService.getcurrentUser();
        Long deptId = user.getDeptId();
        Long deliverId = user.getDeliverId();
        String trayCode = getOperateIdOrderPrefix(user);
        HxOrderOut hxOrderOut = this.findByThelastone();
        int putNumber = 1;
        if (hxOrderOut != null) {
            putNumber = hxOrderOut.getId() + 1;
        }
        DealWithParam dealWithParam = new DealWithParam();
        dealWithParam.setNewCustomersflag(false);
        Map<String, HxBasicGoodsResult> goodsMap = new HashMap<>();
        HxBasicGoodsParam hxgoodsp = new HxBasicGoodsParam();
        hxgoodsp.setGoodsCustomerId(basicCustomer.getId());
        List<HxBasicGoodsResult> hxg = hxBasicGoodsService.findListBySpec(hxgoodsp);
        for (HxBasicGoodsResult gr : hxg) {
            goodsMap.put(gr.getGoodsNumber(), gr);
        }
        for (HxOrderOutExcelItem excelItem : list) {
            if (ToolUtil.isEmpty(excelItem.getGetUnit())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中收货客户不得为空!");
                return data;
            }
            if (ToolUtil.isEmpty(excelItem.getGoodsNumber())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中商品编号不得为空!");
                return data;
            }

            if (ToolUtil.isEmpty(excelItem.getPsNum())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中数量不得为空!");
                return data;
            }

            //通过 导入的订单号 查询是否存在
            HxOrderOutParam opp = new HxOrderOutParam();
            boolean whether2 = false;
            if (ToolUtil.isEmpty(excelItem.getOrderOutNumber())) {
                whether2 = true;
                boolean flags = false;
                for (HxOrderOutParam opp2 : olist) {
                    if (opp2.getGetUnit().equals(excelItem.getGetUnit())) {
                        flags = true;
                        excelItem.setOrderOutNumber(opp2.getOrderOutNumber());
                    }
                }
                if (!flags) {
                    excelItem.setOrderOutNumber(trayCode + "CK" + cn.stylefeng.guns.core.util.DateUtil.getDatesBch() + (putNumber));
                }
            }
            opp.setOrderOutNumber(excelItem.getOrderOutNumber());//订单号
            HxOrderOutResult hxOrderOutResult = this.findBySpec(opp);//状态不等于 作废
            //如果不存在
            if (hxOrderOutResult == null) {
                //新增出库订单
                opp.setCustomerId(hxOrderOutParam.getCustomerId());//客户id
                opp.setCustomerName(basicCustomer.getCustomerName());//客户名称
                opp.setOrderState("待提交");//订单状态
                opp.setPeisongTime(excelItem.getPeisongTime());
                opp.setOrderType(hxOrderOutParam.getOrderType());
                opp.setSetUnit(fh.getPutgoodsName());//装货单位
                opp.setSetUnitId(Long.parseLong(fh.getId().toString()));//装货单位id
                opp.setSetLocation(addressResult.getAddress());//装货地址
                opp.setSetLocationId(Long.parseLong(addressResult.getId().toString()));//装货地址id
                opp.setSetPeople(addressResult.getContacts());//联系人
                opp.setSetTel(addressResult.getTel());//联系电话
                opp.setSetWarehouseId(hxOrderOutParam.getSetWarehouseId());//仓库id
                opp.setSetWarehouse(basicWarehouse.getWarehouseName());//仓库名称
                toDealWith(opp, basicCustomer, excelItem, dealWithParam,user);//处理单位和地址
                opp.setCreateUserName(user.getName());//制单人名称
                opp.setCreateTime(new Date());
                opp.setNotes(excelItem.getNotes());
                opp.setAssociationOrder(excelItem.getAssociationOrder());
                opp.setAssociationOrderType(excelItem.getAssociationOrder());
                opp.setDeliverId(deliverId);//交付id
                opp.setDeptId(deptId);//部门id
                boolean whether = false;//判断单号  是否重复
                for (HxOrderOutParam opp2 : olist) {
                    if (opp2.getOrderOutNumber().equals(opp.getOrderOutNumber())) {
                        whether = true;
                        hxOrderOutResult = new HxOrderOutResult();
                        ToolUtil.copyProperties(opp2, hxOrderOutResult);
                    }
                }
                if (!whether) {
                    olist.add(opp);
                    if (whether2) {
                        putNumber++;
                    }
                    hxOrderOutResult = new HxOrderOutResult();
                    ToolUtil.copyProperties(opp, hxOrderOutResult);
                }
                opp = new HxOrderOutParam();
            } else {
                //如果 导入的客户单号 已存在
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中订单号:" + excelItem.getOrderOutNumber() + "已存在!");
                return data;
            }

            HxBasicGoodsResult hxBasicGoodsResult = goodsMap.get(excelItem.getGoodsNumber());
            if (hxBasicGoodsResult == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中商品" + excelItem.getGoodsNumber() + "系统不存在!请及时同步");
                return data;
            }

            if(ToolUtil.isNotEmpty(excelItem.getPsUnit()) && !excelItem.getPsUnit().equals(hxBasicGoodsResult.getPsUnit())){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚
                data.setSuccess(false);
                data.setMessage("导入数据中商品["+excelItem.getGoodsNumber()+"]的配送单位不匹配，请检查后重试！");
                return data;
            }

            HxOrderOutDetailedParam hxd = new HxOrderOutDetailedParam();
            BigDecimal psNum = new BigDecimal(excelItem.getPsNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);
            BigDecimal goodsVolume = new BigDecimal(hxBasicGoodsResult.getGoodsVolume());
            BigDecimal goodsWeight = new BigDecimal(hxBasicGoodsResult.getGoodsWeight());
            BigDecimal goodsPrice = new BigDecimal("0");

            hxd.setUnit(hxBasicGoodsResult.getPsUnit());
            hxd.setRate(hxBasicGoodsResult.getPsRate());
            BigDecimal psRate = new BigDecimal(hxBasicGoodsResult.getPsRate());
            BigDecimal jibenNum = psRate.multiply(psNum).setScale(3, BigDecimal.ROUND_HALF_DOWN);
            BigDecimal cgRate = new BigDecimal(hxBasicGoodsResult.getCgRate());
            if (psRate.compareTo(cgRate) == -1) {
                //如果配送换算率 小于 采购换算率：  配送体积  =  采购体积/（采购换算率/配送换算率）
                BigDecimal div = cgRate.divide(psRate, 3, BigDecimal.ROUND_HALF_DOWN);
                BigDecimal divv_v = goodsVolume.divide(div, 4, BigDecimal.ROUND_HALF_DOWN);
                goodsVolume = divv_v;
                BigDecimal divv_w = goodsWeight.divide(div, 3, BigDecimal.ROUND_HALF_DOWN);
                goodsWeight = divv_w;
            }
            if (psRate.compareTo(cgRate) == 1) {
                //如果配送换算率 大于 采购换算率：  配送体积  =  采购体积*（配送换算率/采购换算率）
                BigDecimal div = psRate.divide(cgRate, 3, BigDecimal.ROUND_HALF_DOWN);
                BigDecimal divv_v = goodsVolume.multiply(div).setScale(4, BigDecimal.ROUND_HALF_DOWN);
                goodsVolume = divv_v;
                BigDecimal divv_w = goodsWeight.multiply(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                goodsWeight = divv_w;
            }
            BigDecimal goodsChargingPs = new BigDecimal(hxBasicGoodsResult.getGoodsChargingPs());
            goodsPrice = psRate.multiply(goodsChargingPs).setScale(3, BigDecimal.ROUND_HALF_DOWN);

            //创建订单明细
            hxd.setOrderOutNumber(hxOrderOutResult.getOrderOutNumber());
            hxd.setGoodsId(Long.parseLong(hxBasicGoodsResult.getId().toString()));
            hxd.setGoodsName(hxBasicGoodsResult.getGoodsName());
            hxd.setGoodsNumber(hxBasicGoodsResult.getGoodsNumber());
            hxd.setGoodsPcode69(hxBasicGoodsResult.getGoodsPcode69());
            hxd.setGoodsXcode69(hxBasicGoodsResult.getGoodsXcode69());
            hxd.setGoodsHcode69(hxBasicGoodsResult.getGoodsHcode69());
            hxd.setGoodsSpecs(hxBasicGoodsResult.getGoodsSpecs());
            hxd.setDismantlingParts(hxBasicGoodsResult.getDismantlingParts());

            hxd.setJibenNum(jibenNum+"");
            hxd.setJibenUnit(hxBasicGoodsResult.getJibenUnit());

            hxd.setPsNum(psNum.toString());

            hxd.setGoodsWeight(goodsWeight.toString());
            hxd.setOutWeight(psNum.multiply(goodsWeight).setScale(3, BigDecimal.ROUND_HALF_DOWN).toString());
            hxd.setGoodsVolume(goodsVolume.toString());
            hxd.setOutVolume(psNum.multiply(goodsVolume).setScale(4, BigDecimal.ROUND_HALF_DOWN).toString());
            hxd.setGoodsPrice(goodsPrice.toString());
            hxd.setOutMoney(psNum.multiply(goodsPrice).setScale(3, BigDecimal.ROUND_HALF_DOWN).toString());
            hxd.setDetailedDate(excelItem.getDetailedDate());
            hxd.setNotes(excelItem.getNotes());

            detailedList.add(hxd);
//            hxd = new HxOrderOutDetailedParam();
        }
        if (detailedList.size() > 0) {
            this.saveBatchList(olist);
            hxOrderOutDetailedService.saveBatchList(detailedList);
        }
        data.setSuccess(true);
        if (dealWithParam.isNewCustomersflag()) {
            data.setCode(450);
            data.setMessage(dealWithParam.getNewCustomers().replaceAll("null", ""));
        }
        return data;
    }

    private void toDealWith(HxOrderOutParam opp, BasicCustomer basicCustomer, HxOrderOutExcelItem excelItem,
                            DealWithParam dealWithParam,User user ) {
        //查询卸货单位 是否存在
        BasicPutgoodsParam bpgp3 = new BasicPutgoodsParam();
        bpgp3.setPutgoodsCustomerId(basicCustomer.getId());//客户id

        if(ToolUtil.isNotEmpty(excelItem.getUnitNumber())){
            bpgp3.setUnitNumber(excelItem.getUnitNumber());//单位编号(Excel导入数据中 的客户编号)
        }else{
            bpgp3.setPutgoodsName(excelItem.getGetUnit());//单位名称  (Excel导入数据中 的收货客户)
        }
//        if (ToolUtil.isNotEmpty(excelItem.getAddress())) {
//            bpgp3.setLocationAddress(excelItem.getAddress());
//        }
        BasicPutgoodsResult bputr2 = basicPutgoodsService.findBySpec(bpgp3, null);
        if (bputr2 == null) {
            bpgp3.setPutgoodsOperateName(basicCustomer.getCustomerName());//客户名称
            bpgp3.setUnitType("门店");
            bpgp3.setDeliverId(user.getDeliverId());
            bpgp3.setDeptId(user.getDeptId());
            bpgp3.setUnitNumber(excelItem.getUnitNumber());//单位编号(Excel导入数据中 的客户编号)
            basicPutgoodsService.add(bpgp3);
            dealWithParam.setNewCustomersflag(true);
            dealWithParam.setNewCustomers(dealWithParam.getNewCustomers() + "新收货单位：" + excelItem.getGetUnit() + "；");
            BasicPutgoodsParam bpgp4 = new BasicPutgoodsParam();
            bpgp4.setPutgoodsCustomerId(basicCustomer.getId());//客户id
            bpgp4.setPutgoodsName(excelItem.getGetUnit());//单位名称
            bputr2 = basicPutgoodsService.findBySpec(bpgp4, null);
        }
        opp.setGetUnit(bputr2.getPutgoodsName());//卸货单位
        opp.setGetUnitId(Long.parseLong(bputr2.getId().toString()));//卸货单位id
        //查询卸货地点 是否存在
        BasicAddressParam bap3 = new BasicAddressParam();
        bap3.setPutgoodsId(Long.parseLong(bputr2.getId().toString()));//单位id
        if (ToolUtil.isNotEmpty(excelItem.getAddress())) {
            bap3.setAddress(excelItem.getAddress());
        }
        BasicAddressResult bar2 = basicAddressService.findBySpec(bap3);//通过单位id 地址 查询
        if (bar2 != null) {
            boolean flag = false;
            opp.setGetLocationId(Long.parseLong(bar2.getId().toString()));//卸货地址id
            if (ToolUtil.isNotEmpty(excelItem.getAddress())) {
                bap3.setAddress(excelItem.getAddress());
                opp.setGetLocation(excelItem.getAddress());//卸货地址
                flag = true;
            } else {
                opp.setGetLocation(bar2.getAddress());//卸货地址
            }
            if (ToolUtil.isNotEmpty(excelItem.getContacts())) {
                bap3.setContacts(excelItem.getContacts());
                opp.setGetPeople(excelItem.getContacts());//联系人
                flag = true;
            } else {
                opp.setGetPeople(bar2.getContacts());//联系人
            }
            if (ToolUtil.isNotEmpty(excelItem.getTel())) {
                bap3.setTel(excelItem.getTel());
                opp.setGetTel(excelItem.getTel());//联系电话
                flag = true;
            } else {
                opp.setGetTel(bar2.getTel());//联系电话
            }
            bap3.setId(bar2.getId());
            if(flag){
                basicAddressService.update(bap3);
            }
        } else if (bar2 == null && ToolUtil.isEmpty(excelItem.getAddress())) {//如果没有地址 并且Excel中收货客户地址 为空，  卸货地址为 单位名称
            bap3.setAddress(bputr2.getPutgoodsName());//地点 为单位名称
            bap3.setPutgoodsName(bputr2.getPutgoodsName());//单位名称
            bap3.setLongitude("0");
            bap3.setLatitude("0");
            bap3.setSwitchWl("1");
            bap3.setSwitchBj("1500");//提货围栏半径 默认100米
            bap3.setSwitchBj2("2000");//收货围栏半径 默认100米
            basicAddressService.add(bap3);
            BasicAddressParam bap4 = new BasicAddressParam();
            bap4.setPutgoodsId(Long.parseLong(bputr2.getId().toString()));
            bap4.setAddress(bputr2.getPutgoodsName());
            bar2 = basicAddressService.findBySpec(bap4);
            opp.setGetLocation(bar2.getAddress());//卸货地址
            opp.setGetLocationId(Long.parseLong(bar2.getId().toString()));//卸货地址id
            opp.setGetPeople(bar2.getContacts());//联系人
            opp.setGetTel(bar2.getTel());//联系电话
        } else if (bar2 == null && ToolUtil.isNotEmpty(excelItem.getAddress())) {//如果没有地址  Excel中有收货客户地址  新增基础数据 地址
            bap3.setAddress(excelItem.getAddress());//地点 (Excel中收货客户地址)
            bap3.setPutgoodsName(bputr2.getPutgoodsName());//单位名称
            bap3.setLongitude("0");
            bap3.setLatitude("0");
            bap3.setTel(excelItem.getTel());//联系电话 (Excel中的 收货客户电话)
            bap3.setContacts(excelItem.getContacts());
            bap3.setSwitchWl("1");
            bap3.setSwitchBj("1500");//提货围栏半径 默认100米
            bap3.setSwitchBj2("2000");//收货围栏半径 默认100米
            basicAddressService.add(bap3);
            BasicAddressParam bap4 = new BasicAddressParam();
            bap4.setPutgoodsId(Long.parseLong(bputr2.getId().toString()));
            bap4.setAddress(excelItem.getAddress());
            bar2 = basicAddressService.findBySpec(bap4);
            opp.setGetLocation(bar2.getAddress());//卸货地址
            opp.setGetLocationId(Long.parseLong(bar2.getId().toString()));//卸货地址id
            opp.setGetPeople(bar2.getContacts());//联系人
            opp.setGetTel(bar2.getTel());//联系电话
        }
    }

    @Resource
    private BasicAddressService basicAddressService;

    @Resource
    private HxStorageStockService hxStorageStockService;

    @Resource
    private HxStorageOutService hxStorageOutService;

    @Resource
    private HxStorageOutDetailedService hxStorageOutDetailedService;

    @Resource
    private HxBasicPositionGoodsService hxBasicPositionGoodsService;

    @Override
    public boolean saveBatchList(List<HxOrderOutParam> list) {
        return this.baseMapper.saveBatchList(list);
    }

    /**
     * 生成拣货单
     */
    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 400)
    public ResponseData outSingle(HxOrderOutParam hxOrderOutParam, User user, ResponseData data) {
        HxOrderOutParam hxOrderOutParam2 = new HxOrderOutParam();
        hxOrderOutParam2.setOrderOutNumber(hxOrderOutParam.getOrders()[0]);
        HxOrderOutResult hxOrderOutResult = this.findBySpec(hxOrderOutParam2);//其中一条出库订单
        BasicCustomer basicCustomer = basicCustomerService.getById(hxOrderOutResult.getCustomerId());
        String orderOutNumber = "";
        for (String order : hxOrderOutParam.getOrders()) {
            orderOutNumber += order + ";";
        }
        boolean stockYes = false;
        String stockStr = "";
        //校验库存是否足够
        Map<Long,HxStorageOutDetailedResult> djhMap = new HashMap();
        HxStorageOutDetailedParam q = new HxStorageOutDetailedParam();
        q.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
        List<HxStorageOutDetailedResult> djhList = hxStorageOutDetailedService.findZySumList(q);//待拣货 库存
        for(HxStorageOutDetailedResult obj : djhList){
            djhMap.put(obj.getGoodsId(),obj);
        }
        //库存数量
        Map<Long,HxStorageStockResult> stockSumMap = new HashMap();
        HxStorageStockParam q1 = new HxStorageStockParam();
        q1.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
        q1.setStockState("正常");
        List<HxStorageStockResult> stockSumList = hxOrderOutDetailedService.findStockSumList(q1);//查询库存数
        for(HxStorageStockResult obj : stockSumList){
            stockSumMap.put(obj.getGoodsId(),obj);
        }

        List<HxOrderOutDetailedResult> odSumList = hxOrderOutDetailedService.findSumByOrders(hxOrderOutParam);
        for (HxOrderOutDetailedResult odSum : odSumList) {
            BigDecimal psNum = new BigDecimal(odSum.getPsNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//出库数量
            BigDecimal rate = new BigDecimal(odSum.getRate());//出库换算率

            if (djhMap.get(odSum.getGoodsId()) != null) {
                BigDecimal num = new BigDecimal(djhMap.get(odSum.getGoodsId()).getNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//待拣货
                psNum = psNum.add(num);
            }

            BigDecimal snum = new BigDecimal("0");//库存数
            if (stockSumMap.get(odSum.getGoodsId()) != null) {
                BigDecimal kcNum = new BigDecimal(stockSumMap.get(odSum.getGoodsId()).getKcNum());//库存数量
                BigDecimal kcRate = new BigDecimal(stockSumMap.get(odSum.getGoodsId()).getKcRate());//库存换算率
                if (rate.compareTo(kcRate) == -1) {
                    //如果出库换算率 小于 库存换算率：  库存数量  =  库存数量*（库存换算率/出库换算率）
                    BigDecimal div = kcRate.divide(rate, 3, BigDecimal.ROUND_HALF_DOWN);
                    BigDecimal divv_n = kcNum.multiply(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                    kcNum = divv_n;
                }
                if (rate.compareTo(kcRate) == 1) {
                    //如果出库换算率 大于 库存换算率：  库存数量  =   库存数量/（出库换算率/库存换算率）
                    BigDecimal div = rate.divide(kcRate, 3, BigDecimal.ROUND_HALF_DOWN);
                    BigDecimal divv_n = kcNum.divide(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                    kcNum = divv_n;
                }
                snum = kcNum;
            }
            if (psNum.compareTo(snum) == 1) {//如果出库数+待拣货数 > 库存数
                BigDecimal sub = psNum.subtract(snum);
                stockYes = true;
                stockStr += odSum.getGoodsName() + "缺少:" + sub.toString() + "件<br>";

                //去除超库存商品对应的数量
                BigDecimal __psNum = new BigDecimal(odSum.getPsNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//出库数量
                BigDecimal __goodsWeight = new BigDecimal(odSum.getGoodsWeight()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//商品重量
                BigDecimal __goodsVolume = new BigDecimal(odSum.getGoodsVolume()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//商品体积
                BigDecimal __goodsPrice = new BigDecimal(odSum.getGoodsPrice()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//商品单价
                if (__psNum.compareTo(sub) == 1) {
                    odSum.setPsNum(String.valueOf(__psNum.subtract(sub)));
                    odSum.setOutWeight(String.valueOf(__goodsWeight.multiply(__psNum.subtract(sub))));
                    odSum.setOutVolume(String.valueOf(__goodsVolume.multiply(__psNum.subtract(sub))));
                    odSum.setOutMoney(String.valueOf(__goodsPrice.multiply(__psNum.subtract(sub))));
                } else {
                    odSum.setPsNum("0");
                    odSum.setOutWeight("0");
                    odSum.setOutMoney("0");
                }
            }

        }
        //System.out.println("3:"+ DateUtil2.getDateS());
        //删除商品订单数量为0的明细信息。
        List<HxOrderOutDetailedResult> filteredList = odSumList.stream()
                .filter(item -> !item.getPsNum().equals("0"))
                .collect(Collectors.toList());
        odSumList = filteredList;

        //删除后无明细则返回提示
        if (stockYes && odSumList.size() < 1) {
            data.setCode(1);
            data.setSuccess(false);
            data.setMessage(stockStr);
            return data;
        }

        if (stockStr.length() > 0) {
            data.setCode(99);
            data.setMessage(stockStr);
        }

        //按仓库或按区、按体积、数量、商品数，依次推荐
        BigDecimal as = new BigDecimal("0");
        //按调入时间推荐拣货位，实现一品多拣货位需求
        List<HxStorageOutParam> arealist = new ArrayList<HxStorageOutParam>();
        String areaName = "";
        //System.out.println("4:"+ DateUtil2.getDateS());
        for (HxOrderOutDetailedResult odSum : odSumList) {
            HxStorageOutParam o = new HxStorageOutParam();
            HxStorageOutDetailedParam p = new HxStorageOutDetailedParam();

            HxStorageStockParam stockParam = new HxStorageStockParam();
            stockParam.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
            stockParam.setPositionType("拣货位");
            stockParam.setGoodsId(odSum.getGoodsId());
            stockParam.setStockState("正常");
            HxStorageStockResult hxStorageStockResult = hxOrderOutDetailedService.findStockBySpec(stockParam);//查询拣货位库存，按调入时间排序
            if (hxStorageStockResult != null) {
                o.setPalletStorageAreaFlag("否");
                o.setAreaId(hxStorageStockResult.getAreaId());
                o.setAreaName(hxStorageStockResult.getAreaName());
                p.setXlbPositionId(hxStorageStockResult.getPositionXlbId());
                p.setPositionId(hxStorageStockResult.getPositionId());
                p.setPositionNumber(hxStorageStockResult.getPositionNumber());
                p.setPositionPickingorder(hxStorageStockResult.getPositionPickingorder());
                p.setDetailedDate(hxStorageStockResult.getDetailedDate());
                p.setDaoqiDate(hxStorageStockResult.getExpirationDate());
                p.setStockId(Long.parseLong(hxStorageStockResult.getId().toString()));
                p.setTrayId(hxStorageStockResult.getTrayId());
                p.setTrayNumber(hxStorageStockResult.getTrayNumber());
            } else {
                HxBasicPositionGoodsParam check = new HxBasicPositionGoodsParam();
                check.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
                check.setGoodsId(odSum.getGoodsId());
                check.setPositionType("拣货位");
                HxBasicPositionGoodsResult goodsResult = hxBasicPositionGoodsService.findBySpec(check);//查询库位商品关联表
                if (goodsResult != null) {
                    o.setAreaId(goodsResult.getAreaId());
                    o.setAreaName(goodsResult.getAreaName());
                    p.setXlbPositionId(goodsResult.getPositionXlbId());
                    p.setPositionId(goodsResult.getPositionId());
                    p.setPositionNumber(goodsResult.getPositionNumber());
                    p.setPositionPickingorder(goodsResult.getPositionPickingorder());
                } else {
                    data.setCode(2);
                    data.setSuccess(false);
                    data.setMessage(odSum.getGoodsName() + "商品无绑定拣货位，请联系管理员");
                    return data;
                }
            }
            o.setCustomerId(hxOrderOutResult.getCustomerId());
            o.setCustomerName(hxOrderOutResult.getCustomerName());
            o.setStorageState("待拣货");
            o.setStartState("未发车");
            o.setPeisongTime(hxOrderOutResult.getPeisongTime());
            o.setOrderType(hxOrderOutResult.getOrderType());
            o.setXlbSetUnitId(hxOrderOutResult.getXlbSetUnitId());
            o.setSetUnitId(hxOrderOutResult.getSetUnitId());
            o.setSetUnit(hxOrderOutResult.getSetUnit());
            o.setXlbSetWarehouseId(hxOrderOutResult.getXlbSetWarehouseId());
            o.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
            o.setSetWarehouse(hxOrderOutResult.getSetWarehouse());
            o.setXlbClientId(hxOrderOutResult.getXlbClientId());
            o.setGetUnitId(hxOrderOutResult.getGetUnitId());
            o.setGetUnit(hxOrderOutResult.getGetUnit());
            o.setCreateTime(new Date());
            o.setCreateUserName(user.getName());
            o.setAssociationOrder(orderOutNumber);
            o.setDeptId(user.getDeptId());
            o.setDeliverId(user.getDeliverId());
            if (ToolUtil.isNotEmpty(basicCustomer.getAgvRobot())) {
                o.setAgvRobot(basicCustomer.getAgvRobot());
            }

            p.setXlbGoodsId(odSum.getXlbGoodsId());
            p.setGoodsId(odSum.getGoodsId());
            p.setGoodsName(odSum.getGoodsName());
            p.setGoodsNumber(odSum.getGoodsNumber());
            p.setGoodsPcode69(odSum.getGoodsPcode69());
            p.setGoodsXcode69(odSum.getGoodsXcode69());
            p.setGoodsHcode69(odSum.getGoodsHcode69());
            p.setGoodsSpecs(odSum.getGoodsSpecs());
            p.setJibenNum(odSum.getJibenNum());
            p.setJibenUnit(odSum.getJibenUnit());
            p.setUnit(odSum.getUnit());
            p.setRate(odSum.getRate());
            p.setNum(odSum.getPsNum());
            p.setRealNum("");
            p.setQualityNum("0");
            p.setGoodsWeight(odSum.getGoodsWeight());
            p.setOutWeight(odSum.getOutWeight());
            p.setGoodsVolume(odSum.getGoodsVolume());
            p.setOutVolume(odSum.getOutVolume());
            p.setGoodsPrice(odSum.getGoodsPrice());
            p.setOutMoney(odSum.getOutMoney());
            if (ToolUtil.isNotEmpty(odSum.getDismantlingParts())) {
                if (odSum.getDismantlingParts().equals("是")) {//是否拆零
                    p.setScattered("拆零");
                }
            }

            if (hxOrderOutParam.getRule1().equals("按区")) {//按区进行封装
                List<HxStorageOutParam> arealist2 = new ArrayList<HxStorageOutParam>();
                boolean yw = false;
                for (int i = 0; i < arealist.size(); i++) {
                    if (arealist.get(i).getAreaId().equals(o.getAreaId())) {
                        HxStorageOutParam o1 = arealist.get(i);
                        List<HxStorageOutDetailedParam> list1 = o1.getList();
                        list1.add(p);
                        o1.setList(list1);
                        arealist2.add(o1);
                        yw = true;
                    } else {
                        arealist2.add(arealist.get(i));
                    }
                }
                if (!yw) {
                    List<HxStorageOutDetailedParam> list1 = new ArrayList<HxStorageOutDetailedParam>();
                    list1.add(p);
                    o.setList(list1);
                    arealist.add(o);
                } else {
                    arealist = arealist2;
                }
            }
            if (hxOrderOutParam.getRule1().equals("仓库")) {
                if (arealist.size() == 0) {
                    List<HxStorageOutDetailedParam> list1 = new ArrayList<HxStorageOutDetailedParam>();
                    list1.add(p);
                    o.setAreaId(null);
                    o.setList(list1);
                    arealist.add(o);
                    areaName = o.getAreaName() + ";";
                } else {
                    if (areaName.indexOf(o.getAreaName()) == -1) {
                        areaName += o.getAreaName() + ";";
                    }
                    arealist.get(0).setAreaName(areaName);
                    arealist.get(0).getList().add(p);
                }
            }
        }
        //System.out.println("5:"+ DateUtil2.getDateS());
        List<HxStorageOutParam> addlist = new ArrayList<HxStorageOutParam>();//保存的拣货单
        List<HxStorageOutDetailedParam> adddlist = new ArrayList<HxStorageOutDetailedParam>();//保存的拣货单明细
        String trayCode = getOperateIdOrderPrefix(user);
        HxStorageOut hxStorageOut = hxStorageOutService.findByThelastone();
        int putNumber = 1;
        if (hxStorageOut != null) {
            putNumber = hxStorageOut.getId() + 1;
        }

        //整箱和拆零分开
        List<HxStorageOutParam> arealist_z = new ArrayList<HxStorageOutParam>();
        List<HxStorageOutParam> arealist_s = new ArrayList<HxStorageOutParam>();
        for(HxStorageOutParam obj : arealist){
            if(obj.getList() != null && obj.getList().size()> 0 && "拆零".equals(obj.getList().get(0).getScattered())){
                arealist_s.add(obj);
            }else{
                arealist_z.add(obj);
            }

        }
        //整箱
        if (hxOrderOutParam.getRule2().equals("体积")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getDVolume())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单体积(整箱)");
                return data;
            }
            BigDecimal dVolume = new BigDecimal(hxOrderOutParam.getDVolume());//每单体积
            if (dVolume.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单体积(整箱)必须大于0");
                return data;
            }
            //System.out.println("6:"+ DateUtil2.getDateS());
            for (int i = 0; i < arealist_z.size(); i++) {
                HxStorageOutParam p = arealist_z.get(i);
                BigDecimal pjdVolume = new BigDecimal("0");//平均每单体积
                BigDecimal sumVolume = new BigDecimal("0");//总体积
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                    sumVolume = sumVolume.add(outVolume);
                }
                int dlbig = 1;
                if (sumVolume.compareTo(as) == 1 && sumVolume.compareTo(dVolume) == 1) {
                    dlbig = sumVolume.divide(dVolume, 0, BigDecimal.ROUND_UP).intValue();//总体积/每单体积 = 单量（进位取整）
                    pjdVolume = sumVolume.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总体积 / 单量 = 平均每单体积
                } else {
                    pjdVolume = dVolume;
                }
                BigDecimal fVolume = new BigDecimal("0");//已分配体积
                int no1 = 0;

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fVolume.compareTo(as) == 0 && no1 == 0) {
                        no1 = 1;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                        continue;
                    }
                    if (fVolume.compareTo(pjdVolume) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                        fVolume = fVolume.add(outVolume);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule2().equals("数量")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getDNums())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单数量(整箱)");
                return data;
            }
            BigDecimal dNums = new BigDecimal(hxOrderOutParam.getDNums());//每单数量
            if (dNums.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单数量(整箱)必须大于0");
                return data;
            }
            for (int i = 0; i < arealist_z.size(); i++) {
                HxStorageOutParam p = arealist_z.get(i);
                BigDecimal pjdNums = new BigDecimal("0");//平均每单数量
                BigDecimal sumNum = new BigDecimal("0");//总数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal num = new BigDecimal(pd.getNum());
                    sumNum = sumNum.add(num);
                }
                int dlbig = 1;
                if (sumNum.compareTo(as) == 1 && sumNum.compareTo(dNums) == 1) {
                    dlbig = sumNum.divide(dNums, 0, BigDecimal.ROUND_UP).intValue();//总数量/每单数量 = 单量（进位取整）
                    pjdNums = sumNum.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总数量 / 单量 = 平均每单数量
                } else {
                    pjdNums = dNums;
                }

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                BigDecimal fNums = new BigDecimal("0");//已分配数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fNums.compareTo(as) == 0) {
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                        continue;
                    }
                    if (fNums.compareTo(pjdNums) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal num = new BigDecimal(pd.getNum());
                        fNums = fNums.add(num);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule2().equals("无")) {
            for (int i = 0; i < arealist_z.size(); i++) {
                HxStorageOutParam p = arealist_z.get(i);
                p.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                addlist.add(p);
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                    adddlist.add(pd);
                }
                putNumber++;
            }
        }
        //拆零
        if (hxOrderOutParam.getRule21().equals("体积")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getSVolume())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单体积(拆零)");
                return data;
            }
            BigDecimal dVolume = new BigDecimal(hxOrderOutParam.getSVolume());//每单体积
            if (dVolume.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单体积(拆零)必须大于0");
                return data;
            }
            //System.out.println("6:"+ DateUtil2.getDateS());
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                BigDecimal pjdVolume = new BigDecimal("0");//平均每单体积
                BigDecimal sumVolume = new BigDecimal("0");//总体积
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                    sumVolume = sumVolume.add(outVolume);
                }
                int dlbig = 1;
                if (sumVolume.compareTo(as) == 1 && sumVolume.compareTo(dVolume) == 1) {
                    dlbig = sumVolume.divide(dVolume, 0, BigDecimal.ROUND_UP).intValue();//总体积/每单体积 = 单量（进位取整）
                    pjdVolume = sumVolume.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总体积 / 单量 = 平均每单体积
                } else {
                    pjdVolume = dVolume;
                }
                BigDecimal fVolume = new BigDecimal("0");//已分配体积
                int no1 = 0;

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fVolume.compareTo(as) == 0 && no1 == 0) {
                        no1 = 1;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                        continue;
                    }
                    if (fVolume.compareTo(pjdVolume) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                        fVolume = fVolume.add(outVolume);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule21().equals("数量")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getSNums())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单(拆零)数量");
                return data;
            }
            BigDecimal dNums = new BigDecimal(hxOrderOutParam.getSNums());//每单数量
            if (dNums.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单数量(拆零)必须大于0");
                return data;
            }
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                BigDecimal pjdNums = new BigDecimal("0");//平均每单数量
                BigDecimal sumNum = new BigDecimal("0");//总数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal num = new BigDecimal(pd.getNum());
                    sumNum = sumNum.add(num);
                }
                int dlbig = 1;
                if (sumNum.compareTo(as) == 1 && sumNum.compareTo(dNums) == 1) {
                    dlbig = sumNum.divide(dNums, 0, BigDecimal.ROUND_UP).intValue();//总数量/每单数量 = 单量（进位取整）
                    pjdNums = sumNum.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总数量 / 单量 = 平均每单数量
                } else {
                    pjdNums = dNums;
                }

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                BigDecimal fNums = new BigDecimal("0");//已分配数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fNums.compareTo(as) == 0) {
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                        continue;
                    }
                    if (fNums.compareTo(pjdNums) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal num = new BigDecimal(pd.getNum());
                        fNums = fNums.add(num);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule21().equals("商品数")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getSNums())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单商品数量(拆零)");
                return data;
            }
            BigDecimal dNums = new BigDecimal(hxOrderOutParam.getSNums());//每单数量
            if (dNums.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单商品数量(拆零)必须大于0");
                return data;
            }
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                BigDecimal pjdNums = new BigDecimal("0");//平均每单数量
                BigDecimal sumNum = new BigDecimal("0");//总数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal num = new BigDecimal(1);
                    sumNum = sumNum.add(num);
                }
                int dlbig = 1;
                if (sumNum.compareTo(as) == 1 && sumNum.compareTo(dNums) == 1) {
                    dlbig = sumNum.divide(dNums, 0, BigDecimal.ROUND_UP).intValue();//总数量/每单数量 = 单量（进位取整）
                    pjdNums = sumNum.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总数量 / 单量 = 平均每单数量
                } else {
                    pjdNums = dNums;
                }

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                BigDecimal fNums = new BigDecimal("0");//已分配数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fNums.compareTo(as) == 0) {
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(1);
                        continue;
                    }
                    if (fNums.compareTo(pjdNums) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal num = new BigDecimal(1);
                        fNums = fNums.add(num);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(1);
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule21().equals("无")) {
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                p.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                addlist.add(p);
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                    adddlist.add(pd);
                }
                putNumber++;
            }
        }

        //托盘信息
        String trayCode2 = getOperateIdOrderPrefix(user) + "-";
        for (HxStorageOutParam p : addlist) {
            p.setTrayNumber(trayCode2 + cn.stylefeng.guns.core.util.DateUtil.getRandomNumber());
            for (HxStorageOutDetailedParam pd : adddlist) {
                if (pd.getStorageNumber().equals(p.getStorageNumber())) {
                    if (ToolUtil.isNotEmpty(pd.getScattered())) {
                        p.setScattered(pd.getScattered());
                        break;
                    }
                }
            }
        }
        //System.out.println("7:"+ DateUtil2.getDateS());
        //校验安全库存
        for (HxStorageOutDetailedParam pd : adddlist) {
            HxStorageStockParam sumHxStorageStockParam = new HxStorageStockParam();
            sumHxStorageStockParam.setPositionId(pd.getPositionId());
            sumHxStorageStockParam.setGoodsId(pd.getGoodsId());
            sumHxStorageStockParam.setStockState("正常");
            HxStorageStockResult sums = hxStorageStockService.sumPositionStock(sumHxStorageStockParam);//现有库存
            HxBasicGoods hxBasicGoods = hxBasicGoodsService.getById(pd.getGoodsId());
            BigDecimal anquanNum = new BigDecimal(hxBasicGoods.getAnquanNum());
            BigDecimal kcNumSum = new BigDecimal("0");
            BigDecimal kcRate = new BigDecimal(hxBasicGoods.getKcRate());
            //判断是否低于安全库存值
            if (sums != null) {
                kcNumSum = new BigDecimal(sums.getKcNum());
            }
            HxStorageOutDetailedParam hxStorageOutDetailedParam2 = new HxStorageOutDetailedParam();
            hxStorageOutDetailedParam2.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
            hxStorageOutDetailedParam2.setPositionId(pd.getPositionId());
            hxStorageOutDetailedParam2.setGoodsId(pd.getGoodsId());
            HxStorageOutDetailedResult djh = hxStorageOutDetailedService.findZySumBySpec(hxStorageOutDetailedParam2);//待拣货 库存
            BigDecimal djhb = new BigDecimal("0");
            if (djh != null) {
                djhb = new BigDecimal(djh.getNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//待拣货
            }
            BigDecimal bdjhb = new BigDecimal(pd.getNum());//本次出库数量
            djhb = djhb.add(bdjhb).setScale(3, BigDecimal.ROUND_HALF_DOWN);
            BigDecimal psRate = new BigDecimal(hxBasicGoods.getPsRate());
            if (djhb.compareTo(as) != 0) {
                if (kcRate.compareTo(psRate) == -1) {
                    //如果库存换算率 小于 配送换算率：  库存数量  =  库存数量*（配送换算率/库存换算率）
                    BigDecimal div = psRate.divide(kcRate);
                    BigDecimal divv_n = djhb.multiply(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                    djhb = divv_n;
                }
                if (kcRate.compareTo(psRate) == 1) {
                    //如果库存换算率 大于 配送换算率：  库存数量  =  库存数量/（库存换算率/配送换算率）
                    BigDecimal div = kcRate.divide(psRate);
                    BigDecimal divv_n = djhb.divide(div, 3, BigDecimal.ROUND_HALF_DOWN);
                    djhb = divv_n;
                }
            }

            HxStorageOffShelfParam hxStorageOffShelfParam = new HxStorageOffShelfParam();
            hxStorageOffShelfParam.setPositionId(pd.getPositionId());
            hxStorageOffShelfParam.setGoodsId(pd.getGoodsId());
            HxStorageOffShelfResult offres = hxStorageOffShelfService.sumOffShelf(hxStorageOffShelfParam);//汇总待下架
            BigDecimal dxj = new BigDecimal("0");
            if (offres != null) {
                dxj = new BigDecimal(offres.getKcNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);
            }
            BigDecimal jhwKc = kcNumSum;
            kcNumSum = kcNumSum.subtract(djhb);
            kcNumSum = kcNumSum.add(dxj);//库存-待拣货+待下架 = 实际可用库存

            //实际可用库存 小于 0  待下架和新增下架任务 急
            String taskFlag = "";

            if (jhwKc.compareTo(djhb) == -1) {
                //拣货库存小于待拣货库存， 待下架任务 急
                hxStorageOffShelfParam.setTaskFlag("急");
                hxStorageOffShelfService.updateTaskFlag(hxStorageOffShelfParam);
            }

            if (kcNumSum.compareTo(as) == -1) {
                //实际可用库存 小于0  新增下架任务 急
                taskFlag = "急";
            }

            //新增下架任务
            if (anquanNum.compareTo(kcNumSum) == 1) {
                //查询库存 生产日期早的
                HxStorageStockParam OffShelfparam = new HxStorageStockParam();
                OffShelfparam.setStockState("正常");
                OffShelfparam.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
                OffShelfparam.setPositionType("存储位");
                OffShelfparam.setGoodsId(pd.getGoodsId());
                OffShelfparam.setNotOffShelf("NotOffShelf");
                List<HxStorageStockResult> OffShelfres = hxStorageStockService.findaddOffShelflist(OffShelfparam);
                int srls = 0;
                while (kcNumSum.compareTo(anquanNum) == -1) {
                    if (OffShelfres == null || srls == OffShelfres.size()) {
                        kcNumSum = anquanNum;
                        continue;
                    }
                    HxStorageStockResult stock = OffShelfres.get(srls);
                    BigDecimal putNum = new BigDecimal(stock.getKcNum());
                    if (putNum.compareTo(as) == 0) {
                        srls++;
                        continue;
                    }
                    kcNumSum = kcNumSum.add(putNum).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                    HxStorageOffShelfParam addOffShelfParam = new HxStorageOffShelfParam();
                    addOffShelfParam.setStatus("待领取");
                    addOffShelfParam.setStockId(Long.parseLong(stock.getId().toString()));
                    addOffShelfParam.setWarehouseId(stock.getWarehouseId());
                    addOffShelfParam.setWarehouseName(stock.getWarehouseName());
                    addOffShelfParam.setPositionId(pd.getPositionId());
                    addOffShelfParam.setPositionNumber(pd.getPositionNumber());
                    addOffShelfParam.setPositionType("拣货位");
                    addOffShelfParam.setOldPositionId(stock.getPositionId());
                    addOffShelfParam.setOldPositionNumber(stock.getPositionNumber());
                    addOffShelfParam.setOldPositionType(stock.getPositionType());
                    addOffShelfParam.setTrayNumber(stock.getTrayNumber());
                    addOffShelfParam.setGoodsId(stock.getGoodsId());
                    addOffShelfParam.setGoodsName(stock.getGoodsName());
                    addOffShelfParam.setGoodsNumber(stock.getGoodsNumber());
                    addOffShelfParam.setGoodsPcode69(stock.getGoodsPcode69());
                    addOffShelfParam.setDetailedDate(stock.getDetailedDate());
                    addOffShelfParam.setKcNum(stock.getKcNum());
                    addOffShelfParam.setJibenNum(stock.getJibenNum());
                    addOffShelfParam.setCreateUserName(user.getName());
                    addOffShelfParam.setDeptId(user.getDeptId());
                    addOffShelfParam.setOperateId(user.getOperateId());
                    addOffShelfParam.setTaskFlag(taskFlag);
                    hxStorageOffShelfService.add(addOffShelfParam);
                    srls++;
                }
            }
        }
        //System.out.println("8:"+ DateUtil2.getDateS());
        if (addlist.size() > 0) {
            for (String order : hxOrderOutParam.getOrders()) {
                UpdateWrapper<HxOrderOut> updateWrapper = new UpdateWrapper<HxOrderOut>();
                updateWrapper.set("order_state", "已生成");
                updateWrapper.set("submit_user_name", user.getName());
                updateWrapper.set("submit_time", new Date());
                updateWrapper.eq("order_out_number", order);
                this.update(updateWrapper);
            }
            hxStorageOutService.saveBatchList(addlist);
            hxStorageOutDetailedService.saveBatchList(adddlist);
        }
        //System.out.println("9:"+ DateUtil2.getDateS());
        return ResponseData.success(stockStr);

    }

    /**
     * 生成拣货单
     */
    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 400)
    public ResponseData outSingleJbsl(HxOrderOutParam hxOrderOutParam, User user, ResponseData data) {
        HxOrderOutParam hxOrderOutParam2 = new HxOrderOutParam();
        hxOrderOutParam2.setOrderOutNumber(hxOrderOutParam.getOrders()[0]);
        HxOrderOutResult hxOrderOutResult = this.findBySpec(hxOrderOutParam2);//其中一条出库订单
        BasicCustomer basicCustomer = basicCustomerService.getById(hxOrderOutResult.getCustomerId());

        List<BasicPutgoods> putgoodsList = basicPutgoodsService.lambdaQuery()
                .eq(BasicPutgoods::getPutgoodsCustomerId, basicCustomer.getId())
                .last(" and stock_port != '' ")
                .list();
        Map<String,BasicPutgoods> putgoodsMap = new HashMap<>();
        for(BasicPutgoods obj : putgoodsList){
            putgoodsMap.put(obj.getId().toString(),obj);
        }
        String orderOutNumber = "";
        for (String order : hxOrderOutParam.getOrders()) {
            orderOutNumber += order + ";";
        }
        boolean stockYes = false;
        String stockStr = "";
        //校验库存是否足够
        Map<Long,HxStorageOutDetailedResult> djhMap = new HashMap();
        HxStorageOutDetailedParam q = new HxStorageOutDetailedParam();
        q.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
        List<HxStorageOutDetailedResult> djhList = hxStorageOutDetailedService.findZySumList(q);//待拣货 库存
        for(HxStorageOutDetailedResult obj : djhList){
            djhMap.put(obj.getGoodsId(),obj);
        }
        //库存数量
        Map<Long,HxStorageStockResult> stockSumMap = new HashMap();
        HxStorageStockParam q1 = new HxStorageStockParam();
        q1.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
        q1.setStockState("正常");
        List<HxStorageStockResult> stockSumList = hxOrderOutDetailedService.findStockSumList(q1);//查询库存数
        for(HxStorageStockResult obj : stockSumList){
            stockSumMap.put(obj.getGoodsId(),obj);
        }

        List<HxOrderOutDetailedResult> odSumList = hxOrderOutDetailedService.findSumByOrders(hxOrderOutParam);
        // 订单数量大于托规的，直接存储区拣货
        List<HxStorageOutParam> palletStorageList = new ArrayList<>();
        if("是".equals(basicCustomer.getPalletStorageAreaFlag())){
            // 订单中包含的商品ID
            Set<Integer> idList = new HashSet<>();
            Map<String,BigDecimal> goodsPsNumMap = new HashMap<>();
            for (HxOrderOutDetailedResult odSum : odSumList) {
                if(ToolUtil.isNotEmpty(odSum.getGoodsId())){
                    idList.add(odSum.getGoodsId().intValue());
                    goodsPsNumMap.put(odSum.getGoodsId().toString(),new BigDecimal(odSum.getPsNum()));
                }
            }
            List<HxBasicGoods> hxGoodsList = hxBasicGoodsService.lambdaQuery()
                    .in(HxBasicGoods::getId, idList)
                    .list();

            // 循环判断是否有大于托规的商品信息 若存在则需要存储区贱货任务
            Map<String,BigDecimal> goodsCcqNumMap = new HashMap<>();
            for(HxBasicGoods obj : hxGoodsList){
                if(ToolUtil.isNotEmpty(goodsPsNumMap.get(obj.getId().toString()))){
                    //托盘量
                    BigDecimal goodsSupportvolume = new BigDecimal(obj.getGoodsSupportvolume());
                    BigDecimal platNum = goodsPsNumMap.get(obj.getId().toString()).divide(goodsSupportvolume,0, RoundingMode.DOWN);
                    if(platNum.compareTo(BigDecimal.ZERO) == 1){
                        //根据商品ID查询当前存储区的库存
                        HxStorageStockParam offShelfparam = new HxStorageStockParam();
                        offShelfparam.setStockState("正常");
                        offShelfparam.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
                        offShelfparam.setPositionType("存储位");
                        offShelfparam.setGoodsId(Long.valueOf(obj.getId()));
                        offShelfparam.setNotOffShelf("NotOffShelf");
                        offShelfparam.setKcNum(obj.getGoodsSupportvolume());
                        List<HxStorageStockResult> hxStorageStockResults = hxStorageStockService.findaddOffShelflist(offShelfparam);
                        int platStockCnt = 0;
                        for(HxStorageStockResult __stock : hxStorageStockResults){
                            if(platStockCnt < platNum.intValue()){
                                HxStorageOutParam o = new HxStorageOutParam();
                                HxStorageOutDetailedParam p = new HxStorageOutDetailedParam();
                                //若有默认备货口，则使用默认备货口
                                if(ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString())) && ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getStockPort()) ){
                                    o.setStockPort(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getStockPort());
                                }
                                if(ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString())) && ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getUnitNumber()) ){
                                    o.setGetUnitNumber(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getUnitNumber());
                                }
                                o.setAreaId(__stock.getAreaId());
                                o.setAreaName(__stock.getAreaName());
                                p.setXlbPositionId(__stock.getPositionXlbId());
                                p.setPositionId(__stock.getPositionId());
                                p.setPositionNumber(__stock.getPositionNumber());
                                p.setPositionPickingorder(__stock.getPositionPickingorder());
                                p.setDetailedDate(__stock.getDetailedDate());
                                p.setDaoqiDate(__stock.getExpirationDate());
                                p.setStockId(Long.parseLong(__stock.getId().toString()));
                                p.setTrayId(__stock.getTrayId());
                                p.setTrayNumber(__stock.getTrayNumber());
                                o.setCustomerId(hxOrderOutResult.getCustomerId());
                                o.setCustomerName(hxOrderOutResult.getCustomerName());
                                o.setStorageState("待拣货");
                                o.setStartState("未发车");
                                o.setPeisongTime(hxOrderOutResult.getPeisongTime());
                                o.setOrderType(hxOrderOutResult.getOrderType());
                                o.setXlbSetUnitId(hxOrderOutResult.getXlbSetUnitId());
                                o.setSetUnitId(hxOrderOutResult.getSetUnitId());
                                o.setSetUnit(hxOrderOutResult.getSetUnit());
                                o.setXlbSetWarehouseId(hxOrderOutResult.getXlbSetWarehouseId());
                                o.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
                                o.setSetWarehouse(hxOrderOutResult.getSetWarehouse());
                                o.setXlbClientId(hxOrderOutResult.getXlbClientId());
                                o.setGetUnitId(hxOrderOutResult.getGetUnitId());
                                o.setGetUnit(hxOrderOutResult.getGetUnit());
                                o.setCreateTime(new Date());
                                o.setCreateUserName(user.getName());
                                o.setAssociationOrder(orderOutNumber);
                                o.setDeptId(user.getDeptId());
                                o.setDeliverId(user.getDeliverId());

                                p.setXlbGoodsId(obj.getGoodsXlbId());
                                p.setGoodsId(Long.valueOf(obj.getId()));
                                p.setGoodsName(obj.getGoodsName());
                                p.setGoodsNumber(obj.getGoodsNumber());
                                p.setGoodsPcode69(obj.getGoodsPcode69());
                                p.setGoodsXcode69(obj.getGoodsXcode69());
                                p.setGoodsHcode69(obj.getGoodsHcode69());
                                p.setGoodsSpecs(obj.getGoodsSpecs());
                                BigDecimal jbsum = goodsSupportvolume.multiply(new BigDecimal(obj.getPsRate()));
                                p.setJibenNum(jbsum.toString());
                                p.setJibenUnit(obj.getJibenUnit());
                                p.setUnit(obj.getPsUnit());
                                p.setRate(obj.getPsRate());
                                p.setNum(goodsSupportvolume.toString());
                                p.setRealNum("");
                                p.setQualityNum("0");
                                p.setGoodsWeight(obj.getGoodsWeight());
                                p.setOutWeight(jbsum.multiply(new BigDecimal(obj.getGoodsWeight())).toString());
                                p.setGoodsVolume(obj.getGoodsVolume());
                                p.setOutVolume(jbsum.multiply(new BigDecimal(obj.getGoodsVolume())).toString());
                                p.setGoodsPrice(obj.getGoodsChargingPs());
                                p.setOutMoney(jbsum.multiply(new BigDecimal(obj.getGoodsChargingPs())).toString());
                                if (ToolUtil.isNotEmpty(obj.getDismantlingParts())) {
                                    if (obj.getDismantlingParts().equals("是")) {//是否拆零
                                        p.setScattered("拆零");
                                    }
                                }
                                platStockCnt++;
                                List<HxStorageOutDetailedParam> list1 = new ArrayList<HxStorageOutDetailedParam>();
                                list1.add(p);
                                o.setList(list1);
                                o.setPalletStorageAreaFlag("是");
                                palletStorageList.add(o);
                                // 将库存状态改位 待拣货
                                hxStorageStockService.lambdaUpdate()
                                        .eq(HxStorageStock::getId,__stock.getId())
                                        .set(HxStorageStock::getStockState,"待拣货")
                                        .update();
                            }
                        }
                        //添加整托的需要去除对应数量
                        BigDecimal subNum = goodsSupportvolume.multiply(new BigDecimal(platStockCnt));
                        goodsCcqNumMap.put(obj.getId().toString(),subNum);
                    }
                }
            }
            //生成存储区拣货任务的 需要从明细中去掉，然后分拣区分拣
            for (HxOrderOutDetailedResult odSum : odSumList) {
                if(ToolUtil.isNotEmpty(goodsCcqNumMap.get(odSum.getGoodsId().toString()))){
                    BigDecimal psnum = new BigDecimal(odSum.getPsNum()).subtract(goodsCcqNumMap.get(odSum.getGoodsId().toString()));
                    odSum.setPsNum(psnum.toString());
                    odSum.setJibenNum(String.valueOf(psnum.multiply(new BigDecimal(odSum.getRate()))));
                    odSum.setOutWeight(String.valueOf(new BigDecimal(odSum.getGoodsWeight()).multiply(new BigDecimal(odSum.getJibenNum()))));
                    odSum.setOutVolume(String.valueOf(new BigDecimal(odSum.getGoodsVolume()).multiply(new BigDecimal(odSum.getJibenNum()))));
                    odSum.setOutMoney(String.valueOf(new BigDecimal(odSum.getGoodsPrice()).multiply(new BigDecimal(odSum.getJibenNum()))));
                }
            }
        }
        //删除商品订单数量为0的明细信息。
        List<HxOrderOutDetailedResult> filteredList = odSumList.stream()
                .filter(item -> !item.getPsNum().equals("0"))
                .collect(Collectors.toList());
        odSumList = filteredList;


        for (HxOrderOutDetailedResult odSum : odSumList) {
            //出库数量
            BigDecimal ckjbsl = new BigDecimal(odSum.getJibenNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//出库数量
            BigDecimal rate = new BigDecimal(odSum.getRate());//出库换算率
            //待拣货基本数量
            BigDecimal djhjbsl = new BigDecimal(0);
            if(djhMap.get(odSum.getGoodsId()) != null){
                djhjbsl = new BigDecimal(djhMap.get(odSum.getGoodsId()).getJibenNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//待拣货
            }

            //库存基本数量
            BigDecimal kcNum = new BigDecimal(0);//库存数量
            if(stockSumMap.get(odSum.getGoodsId()) != null){
                kcNum = stockSumMap.get(odSum.getGoodsId()).getJibenNum();//库存数量
            }
            //出库数+待拣货数
            BigDecimal ckSum = ckjbsl.add(djhjbsl);
            if (ckSum.compareTo(kcNum) == 1) {//如果出库数+待拣货数 > 库存数
                BigDecimal sub = ckSum.subtract(kcNum);
                stockYes = true;
                stockStr += odSum.getGoodsName() + "缺少:" + sub.toString() + odSum.getJibenUnit() + "<br>";
                //基本单位重量
                BigDecimal __goodsWeight = new BigDecimal(odSum.getGoodsWeight()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//商品重量
                BigDecimal __goodsWeightD = __goodsWeight.divide(new BigDecimal(odSum.getPsNum()),3, BigDecimal.ROUND_HALF_DOWN);//商品重量
                //基本单位体积
                BigDecimal __goodsVolume = new BigDecimal(odSum.getGoodsVolume()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//商品体积
                BigDecimal __goodsVolumeD = __goodsVolume.divide(new BigDecimal(odSum.getPsNum()),3, BigDecimal.ROUND_HALF_DOWN);//商品体积
                //基本单位单价
                BigDecimal __goodsPrice = new BigDecimal(odSum.getGoodsPrice()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//商品单价
                BigDecimal __goodsPriceD = __goodsPrice.divide(new BigDecimal(odSum.getPsNum()),3, BigDecimal.ROUND_HALF_DOWN);//商品单价
                //去除超库存商品对应的数量
                if (ckjbsl.compareTo(sub) == 1) {
                    //单位数量
                    odSum.setJibenNum(String.valueOf(ckjbsl.subtract(sub)));
                    //配送单位数量
                    odSum.setPsNum(String.valueOf(new BigDecimal(odSum.getJibenNum()).divide(rate,3, BigDecimal.ROUND_HALF_DOWN)));
                    odSum.setOutWeight(String.valueOf(__goodsWeightD.multiply(new BigDecimal(odSum.getJibenNum()))));
                    odSum.setOutVolume(String.valueOf(__goodsVolumeD.multiply(new BigDecimal(odSum.getJibenNum()))));
                    odSum.setOutMoney(String.valueOf(__goodsPriceD.multiply(new BigDecimal(odSum.getJibenNum()))));
                } else {
                    odSum.setPsNum("0");
                    odSum.setOutWeight("0");
                    odSum.setOutMoney("0");
                }
            }

        }
        //System.out.println("3:"+ DateUtil2.getDateS());
        //删除商品订单数量为0的明细信息。
        filteredList = odSumList.stream()
                .filter(item -> !item.getPsNum().equals("0"))
                .collect(Collectors.toList());
        odSumList = filteredList;

        //删除后无明细则返回提示
        if (stockYes && odSumList.size() < 1 && palletStorageList.size() < 1) {
            data.setCode(1);
            data.setSuccess(false);
            data.setMessage(stockStr);
            return data;
        }

        if (stockStr.length() > 0) {
            data.setCode(99);
            data.setMessage(stockStr);
        }

        //查询拣货位库存
        HxStorageStockParam stockParam = new HxStorageStockParam();
        stockParam.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
        stockParam.setPositionType("拣货位");
        stockParam.setStockState("正常");
        for (HxOrderOutDetailedResult odSum : odSumList) {
            stockParam.getGoodsIdLists().add(odSum.getGoodsId());
        }
        Map<String,HxStorageStockResult> hxStorageStockResultMap = new HashMap();
        List<HxStorageStockResult> hxStorageStockResults = hxOrderOutDetailedService.findStockListBySpec(stockParam);//查询拣货位库存，按调入时间排序
        for(HxStorageStockResult obj : hxStorageStockResults){
            String __goodsId = obj.getGoodsId().toString();
            if(hxStorageStockResultMap.get(__goodsId) != null){
                continue;
            }else{
                hxStorageStockResultMap.put(__goodsId,obj);
            }
        }
        //按仓库或按区、按体积、数量、商品数，依次推荐
        BigDecimal as = new BigDecimal("0");
        //按调入时间推荐拣货位，实现一品多拣货位需求
        List<HxStorageOutParam> arealist = new ArrayList<HxStorageOutParam>();
        String areaName = "";
        for (HxOrderOutDetailedResult odSum : odSumList) {
            HxStorageOutParam o = new HxStorageOutParam();
            HxStorageOutDetailedParam p = new HxStorageOutDetailedParam();
            HxStorageStockResult hxStorageStockResult = hxStorageStockResultMap.get(odSum.getGoodsId().toString());
            if (hxStorageStockResult != null) {

                o.setPalletStorageAreaFlag("否");
                o.setAreaId(hxStorageStockResult.getAreaId());
                o.setAreaName(hxStorageStockResult.getAreaName());
                p.setXlbPositionId(hxStorageStockResult.getPositionXlbId());
                p.setPositionId(hxStorageStockResult.getPositionId());
                p.setPositionNumber(hxStorageStockResult.getPositionNumber());
                p.setPositionPickingorder(hxStorageStockResult.getPositionPickingorder());
                p.setDetailedDate(hxStorageStockResult.getDetailedDate());
                p.setDaoqiDate(hxStorageStockResult.getExpirationDate());
                p.setStockId(Long.parseLong(hxStorageStockResult.getId().toString()));
                p.setTrayId(hxStorageStockResult.getTrayId());
                p.setTrayNumber(hxStorageStockResult.getTrayNumber());
            } else {
                HxBasicPositionGoodsParam check = new HxBasicPositionGoodsParam();
                check.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
                check.setGoodsId(odSum.getGoodsId());
                check.setPositionType("拣货位");
                HxBasicPositionGoodsResult goodsResult = hxBasicPositionGoodsService.findBySpec(check);//查询库位商品关联表
                if (goodsResult != null) {
                    o.setAreaId(goodsResult.getAreaId());
                    o.setAreaName(goodsResult.getAreaName());
                    p.setXlbPositionId(goodsResult.getPositionXlbId());
                    p.setPositionId(goodsResult.getPositionId());
                    p.setPositionNumber(goodsResult.getPositionNumber());
                    p.setPositionPickingorder(goodsResult.getPositionPickingorder());
                } else {
                    data.setCode(2);
                    data.setSuccess(false);
                    data.setMessage(odSum.getGoodsName() + "商品["+odSum.getGoodsNumber()+"]无绑定拣货位，请联系管理员");
                    return data;
                }
            }
            o.setCustomerId(hxOrderOutResult.getCustomerId());
            o.setCustomerName(hxOrderOutResult.getCustomerName());
            o.setStorageState("待拣货");
            o.setStartState("未发车");
            o.setPeisongTime(hxOrderOutResult.getPeisongTime());
            o.setOrderType(hxOrderOutResult.getOrderType());
            o.setXlbSetUnitId(hxOrderOutResult.getXlbSetUnitId());
            o.setSetUnitId(hxOrderOutResult.getSetUnitId());
            o.setSetUnit(hxOrderOutResult.getSetUnit());
            o.setXlbSetWarehouseId(hxOrderOutResult.getXlbSetWarehouseId());
            o.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
            o.setSetWarehouse(hxOrderOutResult.getSetWarehouse());
            o.setXlbClientId(hxOrderOutResult.getXlbClientId());
            o.setGetUnitId(hxOrderOutResult.getGetUnitId());
            o.setGetUnit(hxOrderOutResult.getGetUnit());
            //若有默认备货口，则使用默认备货口
            if(ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString())) && ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getStockPort()) ){
                o.setStockPort(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getStockPort());
            }
            if(ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString())) && ToolUtil.isNotEmpty(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getUnitNumber()) ){
                o.setGetUnitNumber(putgoodsMap.get(hxOrderOutResult.getGetUnitId().toString()).getUnitNumber());
            }
            o.setCreateTime(new Date());
            o.setCreateUserName(user.getName());
            o.setAssociationOrder(orderOutNumber);
            o.setDeptId(user.getDeptId());
            o.setDeliverId(user.getDeliverId());
            if (ToolUtil.isNotEmpty(basicCustomer.getAgvRobot())) {
                o.setAgvRobot(basicCustomer.getAgvRobot());
            }

            p.setXlbGoodsId(odSum.getXlbGoodsId());
            p.setGoodsId(odSum.getGoodsId());
            p.setGoodsName(odSum.getGoodsName());
            p.setGoodsNumber(odSum.getGoodsNumber());
            p.setGoodsPcode69(odSum.getGoodsPcode69());
            p.setGoodsXcode69(odSum.getGoodsXcode69());
            p.setGoodsHcode69(odSum.getGoodsHcode69());
            p.setGoodsSpecs(odSum.getGoodsSpecs());
            p.setJibenNum(odSum.getJibenNum());
            p.setJibenUnit(odSum.getJibenUnit());
            p.setUnit(odSum.getUnit());
            p.setRate(odSum.getRate());
            p.setNum(odSum.getPsNum());
            p.setRealNum("");
            p.setQualityNum("0");
            p.setGoodsWeight(odSum.getGoodsWeight());
            p.setOutWeight(odSum.getOutWeight());
            p.setGoodsVolume(odSum.getGoodsVolume());
            p.setOutVolume(odSum.getOutVolume());
            p.setGoodsPrice(odSum.getGoodsPrice());
            p.setOutMoney(odSum.getOutMoney());
            if (ToolUtil.isNotEmpty(odSum.getDismantlingParts())) {
                if (odSum.getDismantlingParts().equals("是")) {//是否拆零
                    p.setScattered("拆零");
                }
            }

            if (hxOrderOutParam.getRule1().equals("按区")) {//按区进行封装
                List<HxStorageOutParam> arealist2 = new ArrayList<HxStorageOutParam>();
                boolean yw = false;
                for (int i = 0; i < arealist.size(); i++) {
                    if (arealist.get(i).getAreaId().equals(o.getAreaId())) {
                        HxStorageOutParam o1 = arealist.get(i);
                        List<HxStorageOutDetailedParam> list1 = o1.getList();
                        list1.add(p);
                        o1.setList(list1);
                        arealist2.add(o1);
                        yw = true;
                    } else {
                        arealist2.add(arealist.get(i));
                    }
                }
                if (!yw) {
                    List<HxStorageOutDetailedParam> list1 = new ArrayList<HxStorageOutDetailedParam>();
                    list1.add(p);
                    o.setList(list1);
                    arealist.add(o);
                } else {
                    arealist = arealist2;
                }
            }
            if (hxOrderOutParam.getRule1().equals("仓库")) {
                if (arealist.size() == 0) {
                    List<HxStorageOutDetailedParam> list1 = new ArrayList<HxStorageOutDetailedParam>();
                    list1.add(p);
                    o.setAreaId(null);
                    o.setList(list1);
                    arealist.add(o);
                    areaName = o.getAreaName() + ";";
                } else {
                    if (areaName.indexOf(o.getAreaName()) == -1) {
                        areaName += o.getAreaName() + ";";
                    }
                    arealist.get(0).setAreaName(areaName);
                    arealist.get(0).getList().add(p);
                }
            }
        }
        //System.out.println("5:"+ DateUtil2.getDateS());
        List<HxStorageOutParam> addlist = new ArrayList<HxStorageOutParam>();//保存的拣货单
        List<HxStorageOutDetailedParam> adddlist = new ArrayList<HxStorageOutDetailedParam>();//保存的拣货单明细
        String trayCode = getOperateIdOrderPrefix(user);
        HxStorageOut hxStorageOut = hxStorageOutService.findByThelastone();
        int putNumber = 1;
        if (hxStorageOut != null) {
            putNumber = hxStorageOut.getId() + 1;
        }

        //整箱和拆零分开
        List<HxStorageOutParam> arealist_z = new ArrayList<HxStorageOutParam>();
        List<HxStorageOutParam> arealist_s = new ArrayList<HxStorageOutParam>();
        for(HxStorageOutParam obj : arealist){
            if(obj.getList() != null && obj.getList().size()> 0 && "拆零".equals(obj.getList().get(0).getScattered())){
                arealist_s.add(obj);
            }else{
                arealist_z.add(obj);
            }

        }
        //整箱
        if (hxOrderOutParam.getRule2().equals("体积")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getDVolume())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单体积(整箱)");
                return data;
            }
            BigDecimal dVolume = new BigDecimal(hxOrderOutParam.getDVolume());//每单体积
            if (dVolume.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单体积(整箱)必须大于0");
                return data;
            }
            //System.out.println("6:"+ DateUtil2.getDateS());
            for (int i = 0; i < arealist_z.size(); i++) {
                HxStorageOutParam p = arealist_z.get(i);
                BigDecimal pjdVolume = new BigDecimal("0");//平均每单体积
                BigDecimal sumVolume = new BigDecimal("0");//总体积
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                    sumVolume = sumVolume.add(outVolume);
                }
                int dlbig = 1;
                if (sumVolume.compareTo(as) == 1 && sumVolume.compareTo(dVolume) == 1) {
                    dlbig = sumVolume.divide(dVolume, 0, BigDecimal.ROUND_UP).intValue();//总体积/每单体积 = 单量（进位取整）
                    pjdVolume = sumVolume.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总体积 / 单量 = 平均每单体积
                } else {
                    pjdVolume = dVolume;
                }
                BigDecimal fVolume = new BigDecimal("0");//已分配体积
                int no1 = 0;

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fVolume.compareTo(as) == 0 && no1 == 0) {
                        no1 = 1;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                        continue;
                    }
                    if (fVolume.compareTo(pjdVolume) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                        fVolume = fVolume.add(outVolume);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule2().equals("数量")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getDNums())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单数量(整箱)");
                return data;
            }
            BigDecimal dNums = new BigDecimal(hxOrderOutParam.getDNums());//每单数量
            if (dNums.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单数量(整箱)必须大于0");
                return data;
            }
            for (int i = 0; i < arealist_z.size(); i++) {
                HxStorageOutParam p = arealist_z.get(i);
                BigDecimal pjdNums = new BigDecimal("0");//平均每单数量
                BigDecimal sumNum = new BigDecimal("0");//总数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal num = new BigDecimal(pd.getNum());
                    sumNum = sumNum.add(num);
                }
                int dlbig = 1;
                if (sumNum.compareTo(as) == 1 && sumNum.compareTo(dNums) == 1) {
                    dlbig = sumNum.divide(dNums, 0, BigDecimal.ROUND_UP).intValue();//总数量/每单数量 = 单量（进位取整）
                    pjdNums = sumNum.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总数量 / 单量 = 平均每单数量
                } else {
                    pjdNums = dNums;
                }

                //排序
                Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                for (int j = 0; j < dlbig; j++) {
                    while(__list.hasNext()){
                        _list.add(__list.next());
                        __list.remove();
                        if(__list.hasNext()){
                            __list.next();
                        }
                    }
                }
                if(__list != null && p.getList().size() > 0){
                    _list.addAll(p.getList());
                }
                p.setList(_list);

                BigDecimal fNums = new BigDecimal("0");//已分配数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fNums.compareTo(as) == 0) {
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                        continue;
                    }
                    if (fNums.compareTo(pjdNums) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal num = new BigDecimal(pd.getNum());
                        fNums = fNums.add(num);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        addlist.add(pp);
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                    }
                }
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule2().equals("无")) {
            for (int i = 0; i < arealist_z.size(); i++) {
                HxStorageOutParam p = arealist_z.get(i);
                p.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                addlist.add(p);
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                    adddlist.add(pd);
                }
                putNumber++;
            }
        }
        //拆零
        if (hxOrderOutParam.getRule21().equals("体积")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getSVolume())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单体积(拆零)");
                return data;
            }
            BigDecimal dVolume = new BigDecimal(hxOrderOutParam.getSVolume());//每单体积
            if (dVolume.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单体积(拆零)必须大于0");
                return data;
            }
            //System.out.println("6:"+ DateUtil2.getDateS());
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                BigDecimal pjdVolume = new BigDecimal("0");//平均每单体积
                BigDecimal sumVolume = new BigDecimal("0");//总体积
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                    sumVolume = sumVolume.add(outVolume);
                }
                int dlbig = 1;
                if (sumVolume.compareTo(as) == 1 && sumVolume.compareTo(dVolume) == 1) {
                    dlbig = sumVolume.divide(dVolume, 0, BigDecimal.ROUND_UP).intValue();//总体积/每单体积 = 单量（进位取整）
                    pjdVolume = sumVolume.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总体积 / 单量 = 平均每单体积
                } else {
                    pjdVolume = dVolume;
                }
                BigDecimal fVolume = new BigDecimal("0");//已分配体积
                int no1 = 0;
                if("眺货位".equals(basicCustomer.getPackOrdType())){
                    //排序
                    Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                    List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                    for (int j = 0; j < dlbig; j++) {
                        while(__list.hasNext()){
                            _list.add(__list.next());
                            __list.remove();
                            if(__list.hasNext()){
                                __list.next();
                            }
                        }
                    }
                    if(__list != null && p.getList().size() > 0){
                        _list.addAll(p.getList());
                    }
                    p.setList(_list);
                }
                int trayNum = 1;
                List<HxStorageOutParam> addList_s = new ArrayList<>();
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fVolume.compareTo(as) == 0 && no1 == 0) {
                        no1 = 1;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        pp.setV1(trayNum+"/");
                        addList_s.add(pp);
//                        addlist.add(pp);
                        trayNum++;
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                        continue;
                    }
                    if (fVolume.compareTo(pjdVolume) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal outVolume = new BigDecimal(pd.getOutVolume());
                        fVolume = fVolume.add(outVolume);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        pp.setV1(trayNum+"/");
                        addList_s.add(pp);
//                        addlist.add(pp);
                        trayNum++;
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fVolume = new BigDecimal(pd.getOutVolume());
                    }
                }
                //拼接箱号
                for(HxStorageOutParam obj : addList_s){
                    obj.setV1(obj.getV1()+addList_s.size());
                }
                addlist.addAll(addList_s);
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule21().equals("数量")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getSNums())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单(拆零)数量");
                return data;
            }
            BigDecimal dNums = new BigDecimal(hxOrderOutParam.getSNums());//每单数量
            if (dNums.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单数量(拆零)必须大于0");
                return data;
            }
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                BigDecimal pjdNums = new BigDecimal("0");//平均每单数量
                BigDecimal sumNum = new BigDecimal("0");//总数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal num = new BigDecimal(pd.getNum());
                    sumNum = sumNum.add(num);
                }
                int dlbig = 1;
                if (sumNum.compareTo(as) == 1 && sumNum.compareTo(dNums) == 1) {
                    dlbig = sumNum.divide(dNums, 0, BigDecimal.ROUND_UP).intValue();//总数量/每单数量 = 单量（进位取整）
                    pjdNums = sumNum.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总数量 / 单量 = 平均每单数量
                } else {
                    pjdNums = dNums;
                }
                if("眺货位".equals(basicCustomer.getPackOrdType())){
                    //排序
                    Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                    List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                    for (int j = 0; j < dlbig; j++) {
                        while(__list.hasNext()){
                            _list.add(__list.next());
                            __list.remove();
                            if(__list.hasNext()){
                                __list.next();
                            }
                        }
                    }
                    if(__list != null && p.getList().size() > 0){
                        _list.addAll(p.getList());
                    }
                    p.setList(_list);
                }
                int trayNum = 1;
                List<HxStorageOutParam> addList_s = new ArrayList<>();
                BigDecimal fNums = new BigDecimal("0");//已分配数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fNums.compareTo(as) == 0) {
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        pp.setV1(trayNum+"/");
                        addList_s.add(pp);
//                        addlist.add(pp);
                        trayNum++;
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                        continue;
                    }
                    if (fNums.compareTo(pjdNums) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal num = new BigDecimal(pd.getNum());
                        fNums = fNums.add(num);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        pp.setV1(trayNum+"/");
                        addList_s.add(pp);
//                        addlist.add(pp);
                        trayNum++;
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(pd.getNum());
                    }
                }
                //拼接箱号
                for(HxStorageOutParam obj : addList_s){
                    obj.setV1(obj.getV1()+addList_s.size());
                }
                addlist.addAll(addList_s);
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule21().equals("商品数")) {
            if (ToolUtil.isEmpty(hxOrderOutParam.getSNums())) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("请输入每单商品数量(拆零)");
                return data;
            }
            BigDecimal dNums = new BigDecimal(hxOrderOutParam.getSNums());//每单数量
            if (dNums.compareTo(as) != 1) {
                data.setCode(2);
                data.setSuccess(false);
                data.setMessage("每单商品数量(拆零)必须大于0");
                return data;
            }
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                BigDecimal pjdNums = new BigDecimal("0");//平均每单数量
                BigDecimal sumNum = new BigDecimal("0");//总数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    BigDecimal num = new BigDecimal(1);
                    sumNum = sumNum.add(num);
                }
                int dlbig = 1;
                if (sumNum.compareTo(as) == 1 && sumNum.compareTo(dNums) == 1) {
                    dlbig = sumNum.divide(dNums, 0, BigDecimal.ROUND_UP).intValue();//总数量/每单数量 = 单量（进位取整）
                    pjdNums = sumNum.divide(new BigDecimal(dlbig), 2, BigDecimal.ROUND_HALF_DOWN);//总数量 / 单量 = 平均每单数量
                } else {
                    pjdNums = dNums;
                }
                if("眺货位".equals(basicCustomer.getPackOrdType())){
                    //排序
                    Iterator<HxStorageOutDetailedParam> __list = p.getList().iterator();
                    List<HxStorageOutDetailedParam> _list = new ArrayList<>();
                    for (int j = 0; j < dlbig; j++) {
                        while(__list.hasNext()){
                            _list.add(__list.next());
                            __list.remove();
                            if(__list.hasNext()){
                                __list.next();
                            }
                        }
                    }
                    if(__list != null && p.getList().size() > 0){
                        _list.addAll(p.getList());
                    }
                    p.setList(_list);
                }
                int trayNum = 1;
                List<HxStorageOutParam> addList_s = new ArrayList<>();
                BigDecimal fNums = new BigDecimal("0");//已分配数量
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    if (fNums.compareTo(as) == 0) {
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        pp.setV1(trayNum+"/");
                        addList_s.add(pp);
//                        addlist.add(pp);
                        trayNum++;
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(1);
                        continue;
                    }
                    if (fNums.compareTo(pjdNums) == -1) {
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        BigDecimal num = new BigDecimal(1);
                        fNums = fNums.add(num);
                    } else {
                        putNumber++;
                        HxStorageOutParam pp = new HxStorageOutParam();
                        ToolUtil.copyProperties(p, pp);
                        pp.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        pp.setV1(trayNum+"/");
                        addList_s.add(pp);
//                        addlist.add(pp);
                        trayNum++;
                        pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                        adddlist.add(pd);
                        fNums = new BigDecimal(1);
                    }
                }
                //拼接箱号
                for(HxStorageOutParam obj : addList_s){
                    obj.setV1(obj.getV1()+addList_s.size());
                }
                addlist.addAll(addList_s);
                putNumber++;
            }
        }else if (hxOrderOutParam.getRule21().equals("无")) {
            for (int i = 0; i < arealist_s.size(); i++) {
                HxStorageOutParam p = arealist_s.get(i);
                p.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                p.setV1("1/1");
                addlist.add(p);
                for (HxStorageOutDetailedParam pd : p.getList()) {
                    pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                    adddlist.add(pd);
                }
                putNumber++;
            }
        }

        //整托拣货单
        for (int i = 0; i < palletStorageList.size(); i++) {
            HxStorageOutParam p = palletStorageList.get(i);
            p.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
            addlist.add(p);
            for (HxStorageOutDetailedParam pd : p.getList()) {
                pd.setStorageNumber(trayCode + "JH" + cn.stylefeng.guns.core.util.DateUtil.getDateBch() + (putNumber));
                adddlist.add(pd);
            }
            putNumber++;
        }

        //托盘信息
        String trayCode2 = getOperateIdOrderPrefix(user) + "-";
        for (HxStorageOutParam p : addlist) {
            p.setTrayNumber(trayCode2 + cn.stylefeng.guns.core.util.DateUtil.getRandomNumber());
            for (HxStorageOutDetailedParam pd : adddlist) {
                if (pd.getStorageNumber().equals(p.getStorageNumber())) {
                    if (ToolUtil.isNotEmpty(pd.getScattered())) {
                        p.setScattered(pd.getScattered());
                        break;
                    }
                }
            }
        }
        //校验安全库存  改为定时任务生成下架任务
//        for (HxStorageOutDetailedParam pd : adddlist) {
//            HxStorageStockParam sumHxStorageStockParam = new HxStorageStockParam();
//            sumHxStorageStockParam.setPositionId(pd.getPositionId());
//            sumHxStorageStockParam.setGoodsId(pd.getGoodsId());
//            sumHxStorageStockParam.setStockState("正常");
//            HxStorageStockResult sums = hxStorageStockService.sumPositionStock(sumHxStorageStockParam);//现有库存
//            HxBasicGoods hxBasicGoods = hxBasicGoodsService.getById(pd.getGoodsId());
//            BigDecimal anquanNum = new BigDecimal(hxBasicGoods.getAnquanNum());
//            BigDecimal kcNumSumJbdw = new BigDecimal("0");
//            BigDecimal kcRate = new BigDecimal(hxBasicGoods.getKcRate());
//            //判断是否低于安全库存值
//            if (sums != null) {
//                kcNumSumJbdw = sums.getJibenNum();
//            }
//            HxStorageOutDetailedParam hxStorageOutDetailedParam2 = new HxStorageOutDetailedParam();
//            hxStorageOutDetailedParam2.setSetWarehouseId(hxOrderOutResult.getSetWarehouseId());
//            hxStorageOutDetailedParam2.setPositionId(pd.getPositionId());
//            hxStorageOutDetailedParam2.setGoodsId(pd.getGoodsId());
//            HxStorageOutDetailedResult djh = hxStorageOutDetailedService.findZySumBySpec(hxStorageOutDetailedParam2);//待拣货 库存
//            BigDecimal djhb = new BigDecimal("0");
//            if (djh != null) {
//                djhb = new BigDecimal(djh.getJibenNum()).setScale(3, BigDecimal.ROUND_HALF_DOWN);//待拣货
//            }
//            BigDecimal bdjhb = new BigDecimal(pd.getJibenNum());//本次出库数量
//            djhb = djhb.add(bdjhb).setScale(3, BigDecimal.ROUND_HALF_DOWN);
//
//            BigDecimal psRate = new BigDecimal(hxBasicGoods.getPsRate());
//            HxStorageOffShelfParam hxStorageOffShelfParam = new HxStorageOffShelfParam();
//            hxStorageOffShelfParam.setPositionId(pd.getPositionId());
//            hxStorageOffShelfParam.setGoodsId(pd.getGoodsId());
//            HxStorageOffShelfResult offres = hxStorageOffShelfService.sumOffShelf(hxStorageOffShelfParam);//汇总待下架
//            BigDecimal dxj = new BigDecimal("0");
//            if (offres != null) {
//                dxj = offres.getJibenNum();
//            }
//            BigDecimal jhwKc = kcNumSumJbdw;
//            kcNumSumJbdw = kcNumSumJbdw.subtract(djhb);
//            kcNumSumJbdw = kcNumSumJbdw.add(dxj);//库存-待拣货+待下架 = 实际可用库存
//
//            //实际可用库存 小于 0  待下架和新增下架任务 急
//            String taskFlag = "";
//
//            if (jhwKc.compareTo(djhb) == -1) {
//                //拣货库存小于待拣货库存， 待下架任务 急
//                hxStorageOffShelfParam.setTaskFlag("急");
//                hxStorageOffShelfService.updateTaskFlag(hxStorageOffShelfParam);
//            }
//
//            if (kcNumSumJbdw.compareTo(as) == -1) {
//                //实际可用库存 小于0  新增下架任务 急
//                taskFlag = "急";
//            }
//
//            //安全库存值，换算成基本单位
//            BigDecimal anquanNumJbdw = anquanNum.multiply(new BigDecimal(hxBasicGoods.getKcRate()));
//            //新增下架任务
//            if (anquanNumJbdw.compareTo(kcNumSumJbdw) == 1) {
//                //查询库存 生产日期早的
//                HxStorageStockParam OffShelfparam = new HxStorageStockParam();
//                OffShelfparam.setStockState("正常");
//                OffShelfparam.setWarehouseId(hxOrderOutResult.getSetWarehouseId());
//                OffShelfparam.setPositionType("存储位");
//                OffShelfparam.setGoodsId(pd.getGoodsId());
//                OffShelfparam.setNotOffShelf("NotOffShelf");
//                List<HxStorageStockResult> OffShelfres = hxStorageStockService.findaddOffShelflist(OffShelfparam);
//
//                for(HxStorageStockResult obj : OffShelfres){
//                    HxStorageOffShelfParam addOffShelfParam = new HxStorageOffShelfParam();
//                    addOffShelfParam.setStatus("待领取");
//                    addOffShelfParam.setStockId(obj.getId().longValue());
//                    addOffShelfParam.setWarehouseId(obj.getWarehouseId());
//                    addOffShelfParam.setWarehouseName(obj.getWarehouseName());
//                    addOffShelfParam.setPositionId(pd.getPositionId());
//                    addOffShelfParam.setPositionNumber(pd.getPositionNumber());
//                    addOffShelfParam.setPositionType("拣货位");
//                    addOffShelfParam.setOldPositionId(obj.getPositionId());
//                    addOffShelfParam.setOldPositionNumber(obj.getPositionNumber());
//                    addOffShelfParam.setOldPositionType(obj.getPositionType());
//                    addOffShelfParam.setTrayNumber(obj.getTrayNumber());
//                    addOffShelfParam.setGoodsId(obj.getGoodsId());
//                    addOffShelfParam.setGoodsName(hxBasicGoods.getGoodsName());
//                    addOffShelfParam.setGoodsNumber(hxBasicGoods.getGoodsNumber());
//                    addOffShelfParam.setGoodsPcode69(hxBasicGoods.getGoodsPcode69());
//                    addOffShelfParam.setDetailedDate(obj.getDetailedDate());
//                    addOffShelfParam.setKcNum(obj.getKcNum());
//                    addOffShelfParam.setJibenNum(obj.getJibenNum());
//                    addOffShelfParam.setCreateUserName(user.getName());
//                    addOffShelfParam.setDeptId(user.getDeptId());
//                    addOffShelfParam.setOperateId(user.getOperateId());
//                    addOffShelfParam.setTaskFlag(taskFlag);
//                    hxStorageOffShelfService.add(addOffShelfParam);
//
//                    kcNumSumJbdw = kcNumSumJbdw.add(obj.getJibenNum());
//                    if(anquanNumJbdw.compareTo(kcNumSumJbdw) == -1){
//                        break;
//                    }
//                }
//            }
//        }
        if (addlist.size() > 0) {
            for (String order : hxOrderOutParam.getOrders()) {
                UpdateWrapper<HxOrderOut> updateWrapper = new UpdateWrapper<HxOrderOut>();
                updateWrapper.set("order_state", "已生成");
                updateWrapper.set("submit_user_name", user.getName());
                updateWrapper.set("submit_time", new Date());
                updateWrapper.eq("order_out_number", order);
                this.update(updateWrapper);
            }
            hxStorageOutService.saveBatchList(addlist);
            hxStorageOutDetailedService.saveBatchList(adddlist);
        }
        return ResponseData.success(stockStr);
    }

    /**
     * 按照批次进行提交订单
     * @param hxOrderOutParam
     * @param user
     * @return
     */
    @Override
    public ResponseData btnSubmission3(HxOrderOutParam hxOrderOutParam, User user) {




        return ResponseData.success();
    }

    @Override
    public ResponseData outSingleNew(HxOrderOutParam hxOrderOutParam, User user) {
        ResponseData data = new ResponseData();
        data.setSuccess(true);

        if (hxOrderOutParam.getOrders() == null || hxOrderOutParam.getOrders().length < 1) {
            data.setSuccess(false);
            data.setMessage("请选择订单信息");
            return data;
        }

        Connection conn = null;
        PreparedStatement psQ = null;
        ResultSet rs = null;
        try {
            conn = dataSource.getConnection();
            conn.setAutoCommit(false);
            //判断单据状态，并获取单据对应的货品数量
            psQ = conn.prepareStatement(this.getOrderStatAndGoodCont(hxOrderOutParam.getOrders()));
            rs = psQ.executeQuery();
            Long setWarehouseId = null;
            Long customerId = null;
            while (rs.next()) {
                setWarehouseId = rs.getLong("set_warehouse_id");
                customerId = rs.getLong("customer_id");
                String orderOutNumber = rs.getString("order_out_number");
                String orderState = rs.getString("order_state");
                int mxCnt = rs.getInt("mxCnt");
                if (!"待提交".equals(orderState) && !"撤回".equals(orderState)) {
                    data.setSuccess(false);
                    data.setMessage(orderOutNumber + "单据状态已变化，请刷新重试");
                    return data;
                }
                if (mxCnt <= 0) {
                    data.setSuccess(false);
                    data.setMessage("请先添加商品明细");
                    return data;
                }
            }
            // 获取客户信息
            psQ = conn.prepareStatement(this.getCustomerInfo(customerId));
            rs = psQ.executeQuery();
            BasicCustomer basicCustomer = new BasicCustomer();
            if (rs.next()) {
                basicCustomer.setId(rs.getInt("id"));
                basicCustomer.setAgvRobot(rs.getString("agv_robot"));
            }
            //根据订单获取订单涉及的商品
            psQ = conn.prepareStatement(this.getGoodCont(hxOrderOutParam.getOrders()));
            rs = psQ.executeQuery();
            Map<String, OrderGoodCntVo> orderGoodCntMap = new HashMap<>();
            StringBuffer goodIds = new StringBuffer();
            while (rs.next()) {
                //拼接商品ID
                if (goodIds.length() < 1) {
                    goodIds.append(rs.getString("goods_id"));
                } else {
                    goodIds.append(",").append(rs.getString("goods_id"));
                }
                //缓存当前商品信息
                orderGoodCntMap.put(rs.getString("goods_id"), OrderGoodCntVo.builder()
                        .goodsId(rs.getString("goods_id"))
                        .goodsName(rs.getString("goods_name"))
                        .goodsVolume(rs.getBigDecimal("goods_volume"))
                        .sumPsNum(rs.getBigDecimal("sum_ps_num"))
                        .jibenNum(rs.getBigDecimal("jiben_num"))
                        .sumOutVolume(rs.getBigDecimal("sum_out_volume"))
                        .rate(rs.getBigDecimal("rate"))
                        .unit(rs.getString("unit"))
                        .goodsWeight(rs.getBigDecimal("goods_weight"))
                        .sumOutWeight(rs.getBigDecimal("sum_out_weight"))
                        .goodsPrice(rs.getBigDecimal("goods_price"))
                        .sumOutMoney(rs.getBigDecimal("sum_out_money"))
                        .build());
            }
            //订单商品待拣货数量
            psQ = conn.prepareStatement(this.getStorageGoodCont(goodIds.toString(), setWarehouseId));
            rs = psQ.executeQuery();
            Map<String, StorageGoodCntVo> storageGoodCntMap = new HashMap<>();
            while (rs.next()) {
                //缓存当前商品信息
                storageGoodCntMap.put(rs.getString("goods_id"), StorageGoodCntVo.builder()
                        .goodsId(rs.getString("goods_id"))
                        .num(rs.getBigDecimal("num"))
                        .build());
            }
            //订单商品库存数量
            psQ = conn.prepareStatement(this.getStockGoodCnt(goodIds.toString(), setWarehouseId));
            rs = psQ.executeQuery();
            Map<String, StockGoodCntVo> stockGoodCntVoMap = new HashMap<>();
            while (rs.next()) {
                //缓存当前商品信息
                stockGoodCntVoMap.put(rs.getString("goods_id"), StockGoodCntVo.builder()
                        .goodsId(rs.getString("goods_id"))
                        .kcRate(rs.getBigDecimal("kc_rate"))
                        .kcNum(rs.getBigDecimal("kc_num"))
                        .build());
            }
            //判断库存是否满足当前订单出库数量
            OrderGoodCntVo orderGoodCntVo = null;
            StorageGoodCntVo storageGoodCntVo = null;
            StockGoodCntVo stockGoodCntVo = null;
            StringBuffer stockStr = new StringBuffer();
            for (String goodId : orderGoodCntMap.keySet()) {
                //如果出库换算率 小于 库存换算率：  库存数量  =  库存数量*（库存换算率/出库换算率）
                orderGoodCntVo = orderGoodCntMap.get(goodId);
                storageGoodCntVo = storageGoodCntMap.get(goodId);
                stockGoodCntVo = stockGoodCntVoMap.get(goodId);
                BigDecimal sumPsNum = orderGoodCntVo.getSumPsNum();
                //待拣货
                if (storageGoodCntVo != null) {
                    sumPsNum = sumPsNum.add(storageGoodCntVo.getNum());
                }
                //库存
                if (stockGoodCntVo != null) {
                    BigDecimal kcNum = stockGoodCntVo.getKcNum();//库存数量
                    if (orderGoodCntVo.getRate().compareTo(stockGoodCntVo.getKcRate()) == -1) {
                        //如果出库换算率 小于 库存换算率：  库存数量  =  库存数量*（库存换算率/出库换算率）
                        BigDecimal div = stockGoodCntVo.getKcRate().divide(stockGoodCntVo.getKcRate(), 3, BigDecimal.ROUND_HALF_DOWN);
                        BigDecimal divv_n = kcNum.multiply(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                        kcNum = divv_n;
                    } else if (orderGoodCntVo.getRate().compareTo(stockGoodCntVo.getKcRate()) == 1) {
                        //如果出库换算率 大于 库存换算率：  库存数量  =   库存数量/（出库换算率/库存换算率）
                        BigDecimal div = stockGoodCntVo.getKcRate().divide(stockGoodCntVo.getKcRate(), 3, BigDecimal.ROUND_HALF_DOWN);
                        BigDecimal divv_n = kcNum.divide(div).setScale(3, BigDecimal.ROUND_HALF_DOWN);
                        kcNum = divv_n;
                    }
                    if (sumPsNum.compareTo(kcNum) == 1) {//如果出库数+待拣货数 > 库存数
                        BigDecimal sub = sumPsNum.subtract(kcNum);
                        stockStr.append(orderGoodCntVo.getGoodsName()).append("缺少:");
                        stockStr.append(sub).append("件<br>");
                        // 商品数量减去缺少
                        orderGoodCntVo.setSumPsNum(orderGoodCntVo.getSumOutVolume().subtract(sub));
                        // 商品体积也需要减少对应的体积
                        BigDecimal subVol = sub.multiply(orderGoodCntVo.getGoodsVolume());
                        orderGoodCntVo.setSumOutVolume(orderGoodCntVo.getSumOutVolume().subtract(subVol));
                    }
                } else {
                    stockStr.append(orderGoodCntVo.getGoodsName()).append("缺少:");
                    stockStr.append(sumPsNum).append("件<br>");
                    // 商品数量为0
                    orderGoodCntVo.setSumPsNum(new BigDecimal(0));
                    // 商品体积为0
                    orderGoodCntVo.setSumOutVolume(new BigDecimal(0));
                }
            }
            //获取涉及的商品信息
            psQ = conn.prepareStatement(this.getGoodsInfo(goodIds.toString()));
            rs = psQ.executeQuery();
            Map<String, HxBasicGoodsResult> goodsInfoMap = new HashMap();
            while (rs.next()) {
                goodsInfoMap.put(rs.getString("id"), HxBasicGoodsResult.builder()
                        .id(rs.getInt("id"))
                        .goodsCustomerId(rs.getInt("goods_customer_id"))
                        .goodsName(rs.getString("goods_name"))
                        .goodsNumber(rs.getString("goods_number"))
                        .goodsPcode69(rs.getString("goods_pcode69"))
                        .goodsXcode69(rs.getString("goods_xcode69"))
                        .goodsHcode69(rs.getString("goods_hcode69"))
                        .goodsHelpcode(rs.getString("goods_helpcode"))
                        .goodsHeavybubble(rs.getString("goods_heavybubble"))
                        .goodsSpecs(rs.getString("goods_specs"))
                        .goodsBigtype(rs.getString("goods_bigtype"))
                        .goodsBrand(rs.getString("goods_brand"))
                        .jibenUnit(rs.getString("jiben_unit"))
                        .kcUnit(rs.getString("kc_unit"))
                        .kcRate(rs.getString("kc_rate"))
                        .cgUnit(rs.getString("cg_unit"))
                        .cgRate(rs.getString("cg_rate"))
                        .pfUnit(rs.getString("pf_unit"))
                        .pfRate(rs.getString("pf_rate"))
                        .psUnit(rs.getString("ps_unit"))
                        .anquanNum(rs.getString("anquan_num"))
                        .goodsBottom(rs.getString("goods_bottom"))
                        .goodsLamination(rs.getString("goods_lamination"))
                        .goodsTraylayer(rs.getString("goods_traylayer"))
                        .goodsSupportvolume(rs.getString("goods_supportvolume"))
                        .length(rs.getString("length"))
                        .height(rs.getString("height"))
                        .width(rs.getString("width"))
                        .goodsWeight(rs.getString("goods_weight"))
                        .goodsVolume(rs.getString("goods_volume"))
                        .goodsChargingCg(rs.getString("goods_charging_cg"))
                        .goodsChargingPs(rs.getString("goods_charging_ps"))
                        .goodsChargingPf(rs.getString("goods_charging_pf"))
                        .goodsWarranty(rs.getString("goods_warranty"))
                        .dismantlingParts(rs.getString("dismantling_parts"))
                        .goodsXlbId(rs.getString("goods_xlb_id"))
                        .build());
            }
            //获取仓库的库位信息
            psQ = conn.prepareStatement(this.getPositionInfo(setWarehouseId));
            rs = psQ.executeQuery();
            Map<String, BasicPositionResult> positionInfoMap = new HashMap();
            while (rs.next()) {
                positionInfoMap.put(rs.getString("id"), BasicPositionResult.builder()
                        .id(rs.getInt("id"))
                        .positionState(rs.getString("position_state"))
                        .xAxis(rs.getString("x_axis"))
                        .yAxis(rs.getString("y_axis"))
                        .warehouseId(rs.getInt("warehouse_id"))
                        .warehouseName(rs.getString("warehouse_name"))
                        .warehouseNumber(rs.getString("warehouse_number"))
                        .positionAreaId(rs.getInt("position_area_id"))
                        .areaNumber(rs.getString("area_number"))
                        .positionAreaName(rs.getString("position_area_name"))
                        .positionName(rs.getString("position_name"))
                        .positionNumber(rs.getString("position_number"))
                        .positionType(rs.getString("position_type"))
                        .positionFunction(rs.getString("position_function"))
                        .positionCondition(rs.getString("position_condition"))
                        .positionAreaType(rs.getString("position_area_type"))
                        .traySize(rs.getString("tray_size"))
                        .positionFloor(rs.getString("position_floor"))
                        .positionLine(rs.getString("position_line"))
                        .positionColumn(rs.getString("position_column"))
                        .positionLayer(rs.getString("position_layer"))
                        .positionLength(rs.getString("position_length"))
                        .positionWidth(rs.getString("position_width"))
                        .positionHeight(rs.getString("position_height"))
                        .positionWeight(rs.getString("position_weight"))
                        .positionBarcode(rs.getString("position_barcode"))
                        .positionProduct(rs.getString("position_product"))
                        .positionMeasure(rs.getString("position_measure"))
                        .positionProducttype(rs.getString("position_producttype"))
                        .positionPutorder(rs.getString("position_putorder"))
                        .positionPickingorder(rs.getString("position_pickingorder"))
                        .positionAvailable(rs.getString("position_available"))
                        .positionAlready(rs.getString("position_already"))
                        .positionXlbId(rs.getString("position_xlb_id"))
                        .build());
            }
            //订单商品对应库位及数量
            psQ = conn.prepareStatement(this.getPositionStockGoodCnt(goodIds.toString(), setWarehouseId));
            rs = psQ.executeQuery();
            Map<String, List<PositionStockGoodCntVo>> positionStockGoodCntVoMap = new HashMap<>();
            List<PositionStockGoodCntVo> positionStockGoodCntVoList = null;
            while (rs.next()) {
                //缓存当前商品信息
                if (positionStockGoodCntVoMap.get(rs.getString("goods_id")) != null) {
                    positionStockGoodCntVoMap.get(rs.getString("goods_id")).add(PositionStockGoodCntVo.builder()
                            .id(rs.getLong("id"))
                            .warehouseId(rs.getLong("warehouse_id"))
                            .warehouseName(rs.getString("warehouse_name"))
                            .areaId(rs.getLong("area_id"))
                            .areaName(rs.getString("area_name"))
                            .areaNumber(rs.getString("area_number"))
                            .positionId(rs.getLong("position_id"))
                            .positionNumber(rs.getString("position_number"))
                            .goodsId(rs.getString("goods_id"))
                            .detailedDate(rs.getString("detailed_date"))
                            .expirationDate(rs.getString("expirationDate"))
                            .positionPickingorder(rs.getString("position_pickingorder"))
                            .positionXlbId(rs.getString("position_xlb_id"))
                            .kcNum(rs.getBigDecimal("kc_rate"))
                            .kcRate(rs.getBigDecimal("kc_num"))
                            .trayId(rs.getLong("tray_id"))
                            .trayNumber(rs.getString("tray_number"))
                            .build());
                } else {
                    positionStockGoodCntVoList = new ArrayList<>();
                    positionStockGoodCntVoList.add(PositionStockGoodCntVo.builder()
                            .id(rs.getLong("id"))
                            .warehouseId(rs.getLong("warehouse_id"))
                            .warehouseName(rs.getString("warehouse_name"))
                            .areaId(rs.getLong("area_id"))
                            .areaName(rs.getString("area_name"))
                            .areaNumber(rs.getString("area_number"))
                            .positionId(rs.getLong("position_id"))
                            .positionNumber(rs.getString("position_number"))
                            .goodsId(rs.getString("goods_id"))
                            .detailedDate(rs.getString("detailed_date"))
                            .expirationDate(rs.getString("expirationDate"))
                            .positionPickingorder(rs.getString("position_pickingorder"))
                            .positionXlbId(rs.getString("position_xlb_id"))
                            .kcNum(rs.getBigDecimal("kc_rate"))
                            .kcRate(rs.getBigDecimal("kc_num"))
                            .trayId(rs.getLong("tray_id"))
                            .trayNumber(rs.getString("tray_number"))
                            .build());
                    positionStockGoodCntVoMap.put(rs.getString("goods_id"), positionStockGoodCntVoList);
                }
            }
            //商品绑定库位
            psQ = conn.prepareStatement(this.getPositionGoodRel(goodIds.toString(), setWarehouseId));
            rs = psQ.executeQuery();
            Map<String, List<PositionGoodRelVo>> positionGoodRelMap = new HashMap<>();
            List<PositionGoodRelVo> positionGoodRelVoList = null;
            while (rs.next()) {
                if (positionGoodRelMap.get(rs.getString("goods_id")) != null) {
                    positionGoodRelMap.get(rs.getString("goods_id")).add(PositionGoodRelVo.builder()
                            .id(rs.getLong("id"))
                            .goodsId(rs.getString("goods_id"))
                            .positionId(rs.getString("position_id"))
                            .build());
                } else {
                    positionGoodRelVoList = new ArrayList<>();
                    positionGoodRelVoList.add(PositionGoodRelVo.builder()
                            .id(rs.getLong("id"))
                            .goodsId(rs.getString("goods_id"))
                            .positionId(rs.getString("position_id"))
                            .build());
                    positionGoodRelMap.put(rs.getString("goods_id"), positionGoodRelVoList);
                }
            }

            //商品使用库位
            HxStorageOutParam o = null;
            HxStorageOutDetailedParam p = null;
            List<HxStorageOutDetailedParam> pList = new ArrayList<>();
            String outFlag = "";
            for (String goodId : orderGoodCntMap.keySet()) {
                //订单商品信息
                orderGoodCntVo = orderGoodCntMap.get(goodId);
                //商品对应拣货位
                positionStockGoodCntVoList = positionStockGoodCntVoMap.get(goodId);
                //商品对应绑定库位
                positionGoodRelVoList = positionGoodRelMap.get(goodId);
                //订单商品数量大于0
                if (orderGoodCntVo.getSumPsNum().compareTo(new BigDecimal(0)) == 1) {
                    //如果拣货位有货，则拣货位进行拣选，若拣货位没有，从商品绑定库位拣货，否则报异常
                    if (positionStockGoodCntVoList != null && positionStockGoodCntVoList.size() > 0) {
                        p.setXlbPositionId(positionStockGoodCntVoList.get(0).getPositionXlbId());
                        p.setPositionId(positionStockGoodCntVoList.get(0).getPositionId());
                        p.setPositionNumber(positionStockGoodCntVoList.get(0).getPositionNumber());
                        p.setPositionPickingorder(positionStockGoodCntVoList.get(0).getPositionPickingorder());
                        p.setDetailedDate(positionStockGoodCntVoList.get(0).getDetailedDate());
                        p.setDaoqiDate(positionStockGoodCntVoList.get(0).getExpirationDate());
                        p.setStockId(Long.parseLong(positionStockGoodCntVoList.get(0).getId().toString()));
                        p.setTrayId(positionStockGoodCntVoList.get(0).getTrayId());
                        p.setTrayNumber(positionStockGoodCntVoList.get(0).getTrayNumber());
                    } else if (positionGoodRelVoList != null && positionGoodRelVoList.size() > 0) {
                        p.setXlbPositionId(positionInfoMap.get(positionGoodRelVoList.get(0).getPositionId()).getPositionXlbId());
                        p.setPositionId(Long.valueOf(positionGoodRelVoList.get(0).getPositionId()));
                        p.setPositionNumber(positionInfoMap.get(positionGoodRelVoList.get(0).getPositionId()).getPositionNumber());
                        p.setPositionPickingorder(positionInfoMap.get(positionGoodRelVoList.get(0).getPositionId()).getPositionPickingorder());
                    } else {
                        data.setCode(2);
                        data.setSuccess(false);
                        data.setMessage(orderGoodCntVo.getGoodsName() + "商品无绑定拣货位，请联系管理员");
                        return data;
                    }
                }
                p.setXlbGoodsId(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsXlbId());
                p.setGoodsId(Long.valueOf(orderGoodCntVo.getGoodsId()));
                p.setGoodsName(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsName());
                p.setGoodsNumber(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsNumber());
                p.setGoodsPcode69(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsPcode69());
                p.setGoodsXcode69(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsXcode69());
                p.setGoodsHcode69(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsHcode69());
                p.setGoodsSpecs(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getGoodsSpecs());
                p.setJibenNum(String.valueOf(orderGoodCntVo.getJibenNum()));
                p.setJibenUnit(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getJibenUnit());
                p.setUnit(orderGoodCntVo.getUnit());
                p.setRate(String.valueOf(orderGoodCntVo.getRate()));
                p.setNum(String.valueOf(orderGoodCntVo.getSumPsNum()));
                p.setRealNum("");
                p.setQualityNum("0");
                p.setGoodsWeight(String.valueOf(orderGoodCntVo.getGoodsWeight()));
                p.setOutWeight(String.valueOf(orderGoodCntVo.getSumOutWeight()));
                p.setGoodsVolume(String.valueOf(orderGoodCntVo.getGoodsVolume()));
                p.setOutVolume(String.valueOf(orderGoodCntVo.getSumOutVolume()));
                p.setGoodsPrice(String.valueOf(orderGoodCntVo.getGoodsPrice()));
                p.setOutMoney(String.valueOf(orderGoodCntVo.getSumOutMoney()));
                if (ToolUtil.isNotEmpty(goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getDismantlingParts())) {
                    if (goodsInfoMap.get(orderGoodCntVo.getGoodsId()).getDismantlingParts().equals("是")) {//是否拆零
                        p.setScattered("拆零");
                    }
                }
            }
            //按仓库或按区、按体积、数量，依次推荐

            //订单商品下架任务数量

            conn.commit();
        } catch (SQLException e) {
            JdbcUtls.rollback(conn);
            e.printStackTrace();
        } finally {
            if (!data.getSuccess()) {
                JdbcUtls.rollback(conn);
            }
            JdbcUtls.closeAll(rs, psQ, conn);
        }
        return ResponseData.success();
    }

    //查询当前单据，已经包含的商品信息
    private String getOrderStatAndGoodCont(String[] orders) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t1.order_out_number ");
        sql.append(",t1.set_warehouse_id ");
        sql.append(",t1.customer_id ");
        sql.append(",t1.order_state ");
        sql.append(",count(t2.goods_id) as mxCnt ");
        sql.append("from hx_order_out t1 ");
        sql.append("left join hx_order_out_detailed t2 ");
        sql.append("on t1.order_out_number = t2.order_out_number ");
        sql.append("where order_state != '作废' ");
        sql.append("and t1.order_out_number in ('");
        sql.append(String.join("','", orders));
        sql.append("') ");
        sql.append("group by t1.order_out_number ");
        return sql.toString();
    }

    /**
     * 获取商品数量
     *
     * @param orders
     * @return
     */
    private String getGoodCont(String[] orders) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t1.goods_id ");
        sql.append(",t1.goods_name ");
        sql.append(",t1.rate ");
        sql.append(",t1.unit ");
        sql.append(",t1.goods_volume ");
        sql.append(",t1.jiben_num ");
        sql.append(",t1.goods_weight ");
        sql.append(",t1.goods_price ");
        sql.append(",sum(t1.out_money) as sum_out_money ");
        sql.append(",sum(t1.out_weight) as sum_out_weight ");
        sql.append(",sum(t1.out_volume) as sum_out_volume ");
        sql.append(",sum(t1.ps_num) as sum_ps_num ");
        sql.append("from hx_order_out_detailed t1 ");
        sql.append("where t1.order_out_number in ('");
        sql.append(String.join("','", orders));
        sql.append("') ");
        sql.append("group by t1.goods_id ");
        return sql.toString();
    }

    /**
     * 获取商品待拣货数量
     *
     * @param goodIds
     * @return
     */
    private String getStorageGoodCont(String goodIds, Long setWarehouseId) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t1.goods_id ");
        sql.append(",round(sum(t1.num), 3) AS num ");
        sql.append("FROM hx_storage_out_detailed t1 ");
        sql.append("INNER JOIN hx_storage_out t2 ");
        sql.append("ON t1.storage_number = t2.storage_number ");
        sql.append("WHERE t2.storage_state IN ('待拣货', '拣货中') ");
        sql.append("and t1.goods_id in (");
        sql.append(goodIds);
        sql.append(") ");
        sql.append("and t2.set_warehouse_id = ").append(setWarehouseId);
        sql.append(" group by t1.goods_id ");
        return sql.toString();
    }

    /**
     * 获取商品待拣货数量
     *
     * @param goodIds
     * @return
     */
    private String getStockGoodCnt(String goodIds, Long setWarehouseId) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t1.goods_id ");
        sql.append(",t1.kc_rate ");
        sql.append(",round(sum(t1.kc_num), 3) AS kc_num ");
        sql.append("FROM hx_storage_stock t1 ");
        sql.append("WHERE t1.stock_state = '正常' ");
        sql.append("and t1.goods_id in (");
        sql.append(goodIds);
        sql.append(") ");
        sql.append("and t1.warehouse_id = ").append(setWarehouseId);
        sql.append(" group by t1.goods_id ");
        return sql.toString();
    }

    /**
     * 获取商品拣货位库存
     *
     * @param goodIds
     * @return
     */
    private String getPositionStockGoodCnt(String goodIds, Long setWarehouseId) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t1.id ");
        sql.append(",t1.warehouse_id ");
        sql.append(",t1.warehouse_name ");
        sql.append(",t1.area_id ");
        sql.append(",t1.area_name ");
        sql.append(",t1.area_number ");
        sql.append(",t1.position_id ");
        sql.append(",t1.position_number ");
        sql.append(",t1.goods_id ");
        sql.append(",t1.detailed_date ");
        sql.append(",DATE_ADD(t1.detailed_date, INTERVAL t1.goods_warranty DAY) AS expirationDate ");
        sql.append(",t2.position_pickingorder ");
        sql.append(",t2.position_xlb_id ");
        sql.append(",t1.kc_rate ");
        sql.append(",t1.kc_num ");
        sql.append(",t1.tray_id ");
        sql.append(",t1.tray_number ");
        sql.append("from hx_storage_stock t1 ");
        sql.append("inner join basic_position t2 ");
        sql.append("on t1.position_id = t2.id ");
        sql.append("WHERE t1.stock_state = '正常' ");
        sql.append("and t1.position_type = '拣货位' ");
        sql.append("and t1.goods_id in (");
        sql.append(goodIds);
        sql.append(") ");
        sql.append("and t1.warehouse_id = ").append(setWarehouseId);
        sql.append(" order by t1.goods_id,t1.transfer_time asc ");
        return sql.toString();
    }

    /**
     * 获取商品的绑定库位
     *
     * @param goodIds
     * @param setWarehouseId
     * @return
     */
    private String getPositionGoodRel(String goodIds, Long setWarehouseId) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t1.id ");
        sql.append(",t1.goods_id ");
        sql.append(",t1.position_id ");
        sql.append("from hx_basic_position_goods t1 ");
        sql.append("WHERE t1.goods_id in (");
        sql.append(goodIds);
        sql.append(") ");
        sql.append("and t1.warehouse_id = ").append(setWarehouseId);
        sql.append(" order by t1.goods_id ");
        return sql.toString();
    }

    /**
     * 获取商品信息
     *
     * @param goodIds
     * @return
     */
    private String getGoodsInfo(String goodIds) {
        StringBuffer sql = new StringBuffer();
        sql.append("t1.id");
        sql.append(",t1.goods_customer_id");
        sql.append(",t1.goods_name");
        sql.append(",t1.goods_number");
        sql.append(",t1.goods_pcode69");
        sql.append(",t1.goods_xcode69");
        sql.append(",t1.goods_hcode69");
        sql.append(",t1.goods_helpcode");
        sql.append(",t1.goods_heavybubble");
        sql.append(",t1.goods_specs");
        sql.append(",t1.goods_bigtype");
        sql.append(",t1.goods_brand");
        sql.append(",t1.jiben_unit");
        sql.append(",t1.kc_unit");
        sql.append(",t1.kc_rate");
        sql.append(",t1.cg_unit");
        sql.append(",t1.cg_rate");
        sql.append(",t1.pf_unit");
        sql.append(",t1.pf_rate");
        sql.append(",t1.ps_unit");
        sql.append(",t1.ps_rate");
        sql.append(",t1.anquan_num");
        sql.append(",t1.goods_bottom");
        sql.append(",t1.goods_lamination");
        sql.append(",t1.goods_traylayer");
        sql.append(",t1.goods_supportvolume");
        sql.append(",t1.length");
        sql.append(",t1.height");
        sql.append(",t1.width");
        sql.append(",t1.goods_weight");
        sql.append(",t1.goods_volume");
        sql.append(",t1.goods_charging_cg");
        sql.append(",t1.goods_charging_ps");
        sql.append(",t1.goods_charging_pf");
        sql.append(",t1.goods_warranty");
        sql.append(",t1.goods_nodes");
        sql.append(",t1.goods_bigtype_dict_id");
        sql.append(",t1.dismantling_parts");
        sql.append(",t1.goods_xlb_id ");
        sql.append("from hx_basic_position_goods t1 ");
        sql.append("WHERE t1.id in (");
        sql.append(goodIds);
        sql.append(") ");
        return sql.toString();
    }

    /**
     * @param setWarehouseId
     * @return
     */
    private String getPositionInfo(Long setWarehouseId) {
        StringBuffer sql = new StringBuffer();
        sql.append("t1.id ");
        sql.append(",t1.position_state ");
        sql.append(",t1.x_axis ");
        sql.append(",t1.y_axis ");
        sql.append(",t1.warehouse_id ");
        sql.append(",t1.warehouse_number ");
        sql.append(",t1.warehouse_name ");
        sql.append(",t1.position_area_id ");
        sql.append(",t1.area_number ");
        sql.append(",t1.position_area_name ");
        sql.append(",t1.position_name ");
        sql.append(",t1.position_number ");
        sql.append(",t1.position_type ");
        sql.append(",t1.position_function ");
        sql.append(",t1.position_condition ");
        sql.append(",t1.position_area_type ");
        sql.append(",t1.tray_size ");
        sql.append(",t1.position_floor ");
        sql.append(",t1.position_line ");
        sql.append(",t1.position_column ");
        sql.append(",t1.position_layer ");
        sql.append(",t1.position_length ");
        sql.append(",t1.position_width ");
        sql.append(",t1.position_height ");
        sql.append(",t1.position_weight ");
        sql.append(",t1.position_barcode ");
        sql.append(",t1.position_product ");
        sql.append(",t1.position_measure ");
        sql.append(",t1.position_producttype ");
        sql.append(",t1.position_putorder ");
        sql.append(",t1.position_pickingorder ");
        sql.append(",t1.position_available ");
        sql.append(",t1.position_already ");
        sql.append(",t1.position_notes ");
        sql.append(",t1.version ");
        sql.append(",t1.position_xlb_id ");
        sql.append("from basic_position t1 ");
        sql.append("where t1.warehouse_id = ").append(setWarehouseId);
        return sql.toString();
    }

    /**
     * 获取客户信息
     *
     * @param customerId
     * @return
     */
    private String getCustomerInfo(Long customerId) {
        StringBuffer sql = new StringBuffer();
        sql.append("select ");
        sql.append("t.id ");
        sql.append(",t.agv_robot ");
        sql.append("from basic_customer t ");
        sql.append("where id = ");
        sql.append(customerId);
        return sql.toString();
    }


    @Autowired
    private BasicTrayService basicTrayService;

    @Autowired
    private HxStorageOffShelfService hxStorageOffShelfService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData revoke(HxOrderOut hxOrderOut, ResponseData data) {
        HxOrderOutParam hxOrderOutParam = new HxOrderOutParam();
        hxOrderOutParam.setId(hxOrderOut.getId());
        hxOrderOutParam.setOrderState("撤回");
        this.update(hxOrderOutParam);//撤回入库订单
        return ResponseData.success();
    }

    @Override
    public List<HxOrderOutResult> findlistAllBySpec(HxOrderOutParam hxOrderOutParam, String condition, Long operateId) {
        return this.baseMapper.findlistAllBySpec(hxOrderOutParam, condition, operateId);
    }

    @Override
    public HxOrderOutResult count(HxOrderOutParam hxOrderOutParam, String condition, Long operateId) {
        return this.baseMapper.count(hxOrderOutParam, condition, operateId);
    }

    @Override
    public List<HxOrderOutResult> findOrderOutNumberListBySpec(HxOrderOutParam orderOutParam1) {
        return this.baseMapper.findOrderOutNumberListBySpec(orderOutParam1);
    }

    @Override
    public void deletebyids(List<Integer> deleteolist) {
        this.baseMapper.deletebyids(deleteolist);
    }

    @Override
    public List<HxOrderOutResult> findlistAllBySpec1(HxOrderOutParam hxOrderOutParam, String condition, Long operateId) {
        return this.baseMapper.findlistAllBySpec1(hxOrderOutParam, condition, operateId);
    }

    @Override
    public HxOrderOutResult count1(HxOrderOutParam hxOrderOutParam, String condition, Long operateId) {
        return this.baseMapper.count1(hxOrderOutParam, condition, operateId);
    }

	@Override
	public List<HxOrderOutResult> findOrderListBySpec(HxOrderOutParam hxop) {
		return this.baseMapper.findOrderListBySpec(hxop);
	}

    @Override
    public LayuiPageInfo findPageByMap(HxOrderOutParam param, String condition, Long operateId) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.findPageByMap(pageContext, param, condition,operateId);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public List<HxOrderOutResult> expExcel(HxOrderOutParam hxop,String condition, Long operateId) {
        return this.baseMapper.expExcel(hxop,condition,operateId);
    }

}
